List of usage examples for org.objectweb.asm Opcodes ACC_PROTECTED
int ACC_PROTECTED
To view the source code for org.objectweb.asm Opcodes ACC_PROTECTED.
Click Source Link
From source file:org.mbte.groovypp.compiler.AccessibilityCheck.java
License:Apache License
public static boolean isAccessible(int modifiers, ClassNode declaringClass, ClassNode placeClass, ClassNode accessType) {/*from w w w . jav a 2s.c o m*/ if (accessType != null && !isAccessible(accessType.getModifiers(), accessType.getOuterClass(), placeClass, null)) return false; if (declaringClass == null) return true; if ((modifiers & Opcodes.ACC_PRIVATE) != 0) { return getToplevelClass(declaringClass).equals(getToplevelClass(placeClass)); } else if ((modifiers & Opcodes.ACC_PROTECTED) != 0) { if (samePackage(declaringClass, placeClass)) return true; while (placeClass != null) { if (placeClass.isDerivedFrom(declaringClass)) { return accessType == null || accessType.isDerivedFrom(placeClass); } if ((placeClass.getModifiers() & Opcodes.ACC_STATIC) != 0) break; placeClass = placeClass.getOuterClass(); } return false; } else if ((modifiers & Opcodes.ACC_PUBLIC) != 0) { return true; } // package local if (!samePackage(declaringClass, placeClass)) return false; // check the entire inheritance chain. ClassNode clazz = null; if (accessType != null) { clazz = accessType; } else { while (placeClass != null) { if (placeClass.isDerivedFrom(declaringClass)) { clazz = placeClass; break; } if ((placeClass.getModifiers() & Opcodes.ACC_STATIC) != 0) break; placeClass = placeClass.getOuterClass(); } } while (clazz != null && !clazz.equals(declaringClass)) { if (!samePackage(declaringClass, clazz)) return false; clazz = clazz.getSuperClass(); } return true; }
From source file:org.mbte.groovypp.compiler.TraitASTTransform.java
License:Apache License
public void visit(ASTNode[] nodes, final SourceUnit source) { ModuleNode module = (ModuleNode) nodes[0]; List<ClassNode> toProcess = new LinkedList<ClassNode>(); final boolean forceTyped = source.getName().endsWith(".gpp"); AnnotationNode pkgTypedAnn = getTypedAnnotation(module.getPackage()); for (ClassNode classNode : module.getClasses()) { boolean process = false; boolean typed = false; for (AnnotationNode ann : classNode.getAnnotations()) { final String withoutPackage = ann.getClassNode().getNameWithoutPackage(); if (withoutPackage.equals("Trait")) { process = true;/*from w ww . jav a 2 s. c o m*/ } if (withoutPackage.equals("Typed")) { typed = true; ann.getClassNode().setRedirect(TypeUtil.TYPED); } } if (forceTyped && !typed) { typed = true; classNode.addAnnotation(pkgTypedAnn != null ? pkgTypedAnn : new AnnotationNode(TypeUtil.TYPED)); } if (process) { toProcess.add(classNode); if (!typed) { classNode.addAnnotation(pkgTypedAnn != null ? pkgTypedAnn : new AnnotationNode(TypeUtil.TYPED)); } } } for (ClassNode classNode : toProcess) { if (classNode.isInterface() || classNode.isEnum() || classNode.isAnnotationDefinition()) { source.addError(new SyntaxException("@Trait can be applied only to <class>", classNode.getLineNumber(), classNode.getColumnNumber())); continue; } if (classNode.getDeclaredConstructors().size() > 0) { ConstructorNode constructor = classNode.getDeclaredConstructors().get(0); source.addError(new SyntaxException("Constructors are not allowed in traits", constructor.getLineNumber(), constructor.getColumnNumber())); continue; } if (classNode.getObjectInitializerStatements().size() > 0) { Statement initializer = classNode.getObjectInitializerStatements().get(0); source.addError(new SyntaxException("Object initializers are not allowed in traits", initializer.getLineNumber(), initializer.getColumnNumber())); continue; } int mod = classNode.getModifiers(); mod &= ~Opcodes.ACC_FINAL; mod |= Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE; classNode.setModifiers(mod); String name = classNode.getNameWithoutPackage() + "$TraitImpl"; String fullName = ASTHelper.dot(classNode.getPackageName(), name); InnerClassNode innerClassNode = new InnerClassNode(classNode, fullName, ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT, ClassHelper.OBJECT_TYPE, new ClassNode[] { classNode }, null); AnnotationNode typedAnn = new AnnotationNode(TypeUtil.TYPED); final Expression member = getTypedAnnotation(classNode).getMember("debug"); if (member != null && member instanceof ConstantExpression && ((ConstantExpression) member).getValue().equals(Boolean.TRUE)) typedAnn.addMember("debug", ConstantExpression.TRUE); innerClassNode.addAnnotation(typedAnn); innerClassNode.setGenericsTypes(classNode.getGenericsTypes()); ClassNode superClass = classNode.getSuperClass(); if (!ClassHelper.OBJECT_TYPE.equals(superClass)) { ClassNode[] ifaces = classNode.getInterfaces(); ClassNode[] newIfaces = new ClassNode[ifaces.length + 1]; newIfaces[0] = superClass; System.arraycopy(ifaces, 0, newIfaces, 1, ifaces.length); classNode.setSuperClass(ClassHelper.OBJECT_TYPE); classNode.setInterfaces(newIfaces); } classNode.getModule().addClass(innerClassNode); innerClassNode.addMethod("getMetaClass", ACC_PUBLIC | ACC_ABSTRACT, ClassHelper.METACLASS_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null); innerClassNode.addMethod("setMetaClass", ACC_PUBLIC | ACC_ABSTRACT, ClassHelper.VOID_TYPE, new Parameter[] { new Parameter(ClassHelper.METACLASS_TYPE, "value") }, ClassNode.EMPTY_ARRAY, null); innerClassNode.addMethod("getProperty", ACC_PUBLIC | ACC_ABSTRACT, ClassHelper.OBJECT_TYPE, new Parameter[] { new Parameter(ClassHelper.STRING_TYPE, "name") }, ClassNode.EMPTY_ARRAY, null); innerClassNode.addMethod("setProperty", ACC_PUBLIC | ACC_ABSTRACT, ClassHelper.VOID_TYPE, new Parameter[] { new Parameter(ClassHelper.STRING_TYPE, "name"), new Parameter(ClassHelper.OBJECT_TYPE, "value") }, ClassNode.EMPTY_ARRAY, null); innerClassNode.addMethod("invokeMethod", ACC_PUBLIC | ACC_ABSTRACT, ClassHelper.OBJECT_TYPE, new Parameter[] { new Parameter(ClassHelper.STRING_TYPE, "name"), new Parameter(ClassHelper.OBJECT_TYPE, "args") }, ClassNode.EMPTY_ARRAY, null); for (FieldNode fieldNode : classNode.getFields()) { // if (fieldNode.isStatic()) // continue; final String getterName = "get" + Verifier.capitalize(fieldNode.getName()); MethodNode getter = classNode.getGetterMethod(getterName); if (getter == null) { getter = classNode.addMethod(getterName, ACC_PUBLIC | ACC_ABSTRACT, fieldNode.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null); addFieldAnnotation(innerClassNode, fieldNode, getter); } // We need the second getter (and setter) to compile non-synthetic first one referring to the field. // The references inside the first one will be retargeted to the second one. final MethodNode realGetter = classNode.addMethod("get$" + fieldNode.getName(), ACC_PUBLIC | ACC_ABSTRACT, fieldNode.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null); addFieldAnnotation(innerClassNode, fieldNode, realGetter); final String setterName = "set" + Verifier.capitalize(fieldNode.getName()); Parameter valueParam = new Parameter(fieldNode.getType(), "$value"); MethodNode setter = classNode.getSetterMethod(setterName); if (setter == null) { setter = classNode.addMethod(setterName, ACC_PUBLIC | ACC_ABSTRACT, ClassHelper.VOID_TYPE, new Parameter[] { valueParam }, ClassNode.EMPTY_ARRAY, null); addFieldAnnotation(innerClassNode, fieldNode, setter); } final MethodNode realSetter = classNode.addMethod("set$" + fieldNode.getName(), ACC_PUBLIC | ACC_ABSTRACT, ClassHelper.VOID_TYPE, new Parameter[] { valueParam }, ClassNode.EMPTY_ARRAY, null); addFieldAnnotation(innerClassNode, fieldNode, realSetter); if (fieldNode.hasInitialExpression()) { final Expression initial = fieldNode.getInitialValueExpression(); fieldNode.setInitialValueExpression(null); final MethodNode initMethod = innerClassNode.addMethod("__init_" + fieldNode.getName(), ACC_PUBLIC | ACC_STATIC, ClassHelper.VOID_TYPE, new Parameter[] { new Parameter(classNode, "$self") }, ClassNode.EMPTY_ARRAY, new BlockStatement()); final PropertyExpression prop = new PropertyExpression(new VariableExpression("$self"), fieldNode.getName()); prop.setSourcePosition(fieldNode); final CastExpression cast = new CastExpression(fieldNode.getType(), initial); cast.setSourcePosition(initial); final BinaryExpression assign = new BinaryExpression(prop, Token.newSymbol(Types.ASSIGN, -1, -1), cast); assign.setSourcePosition(initial); final ExpressionStatement assignExpr = new ExpressionStatement(assign); assignExpr.setSourcePosition(initial); ((BlockStatement) initMethod.getCode()).addStatement(assignExpr); } innerClassNode.addField(fieldNode); } classNode.getFields().clear(); classNode.getProperties().clear(); for (MethodNode methodNode : classNode.getMethods()) { if (methodNode.getCode() == null) continue; if (methodNode.isStatic()) { source.addError(new SyntaxException("Static methods are not allowed in traits", methodNode.getLineNumber(), methodNode.getColumnNumber())); } if (!methodNode.isPublic()) { source.addError(new SyntaxException("Non-public methods are not allowed in traits", methodNode.getLineNumber(), methodNode.getColumnNumber())); } mod = methodNode.getModifiers(); mod &= ~(Opcodes.ACC_FINAL | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE); mod |= Opcodes.ACC_ABSTRACT | Opcodes.ACC_PUBLIC; methodNode.setModifiers(mod); Parameter[] parameters = methodNode.getParameters(); Parameter[] newParameters = new Parameter[parameters.length + 1]; final Parameter self = new Parameter(classNode, "$self"); newParameters[0] = self; System.arraycopy(parameters, 0, newParameters, 1, parameters.length); MethodNode newMethod = innerClassNode.addMethod(methodNode.getName(), ACC_PUBLIC, methodNode.getReturnType(), newParameters, ClassNode.EMPTY_ARRAY, methodNode.getCode()); ArrayList<GenericsType> gt = new ArrayList<GenericsType>(); if (classNode.getGenericsTypes() != null) for (int i = 0; i < classNode.getGenericsTypes().length; i++) { GenericsType genericsType = classNode.getGenericsTypes()[i]; gt.add(genericsType); } if (methodNode.getGenericsTypes() != null) for (int i = 0; i < methodNode.getGenericsTypes().length; i++) { GenericsType genericsType = methodNode.getGenericsTypes()[i]; gt.add(genericsType); } if (!gt.isEmpty()) newMethod.setGenericsTypes(gt.toArray(new GenericsType[gt.size()])); AnnotationNode annotationNode = new AnnotationNode(TypeUtil.HAS_DEFAULT_IMPLEMENTATION); annotationNode.addMember("value", new ClassExpression(innerClassNode)); methodNode.addAnnotation(annotationNode); methodNode.setCode(null); } } }
From source file:org.mule.tools.maven.plugin.module.analyze.asm.AccessUtils.java
License:Open Source License
public static boolean isProtected(int access) { return (access & Opcodes.ACC_PROTECTED) == Opcodes.ACC_PROTECTED; }
From source file:org.openspotlight.bundle.language.java.resolver.JavaGraphNodeSupport.java
License:Open Source License
/** * Adds the type on current context. This method should be used on current classpath elements only. The types declared outside * this classpath should be added with method {@link #addTypeOnAbstractContext(Class, String, String)}. * /*from w w w . j a v a 2 s. com*/ * @param nodeType the node type * @param packageName the package name * @param nodeName the node name * @param access the access * @param parentType the parent type, if null will use package as parent * @return the t * @throws Exception the exception */ @SuppressWarnings("unchecked") public <T extends JavaType> T addTypeOnCurrentContext(final Class<T> nodeType, final String packageName, final String nodeName, final int access, final Node parentType) throws Exception { if (logger.isDebugEnabled()) { logger.debug(" adding type on current context " + packageName + "_" + nodeName + " with parent " + (parentType != null ? parentType.getName() : "null")); } if (usingCache && nodesFromThisContext.containsKey(packageName + nodeName)) { return (T) nodesFromThisContext.get(packageName + nodeName); } if (JavaTypePrimitive.class.equals(nodeType)) { final T newType = abstractContextRootNode.addChildNode(nodeType, nodeName); newType.setSimpleName(nodeName); newType.setQualifiedName(nodeName); return newType; } final JavaPackage newPackage = currentContextRootNode.addChildNode(JavaPackage.class, packageName); T newType = null; if (parentType != null) { newType = parentType.addChildNode(nodeType, nodeName); } else { newType = newPackage.addChildNode(nodeType, nodeName); } newType.setSimpleName(nodeName); newType.setQualifiedName(Strings.tryToRemoveBegginingFrom(JavaConstants.DEFAULT_PACKAGE + ".", packageName + "." + nodeName.replaceAll("[$]", "."))); session.addLink(PackageType.class, newPackage, newType, false); final boolean isPublic = (access & Opcodes.ACC_PUBLIC) != 0; final boolean isPrivate = (access & Opcodes.ACC_PRIVATE) != 0; final boolean isStatic = (access & Opcodes.ACC_STATIC) != 0; final boolean isFinal = (access & Opcodes.ACC_FINAL) != 0; final boolean isProtected = (access & Opcodes.ACC_PROTECTED) != 0; newType.setPublic(isPublic); newType.setPrivate(isPrivate); newType.setStatic(isStatic); newType.setFinal(isFinal); newType.setProtected(isProtected); final JavaPackage newAbstractPackage = abstractContextRootNode.addChildNode(JavaPackage.class, packageName); final JavaType newAbstractType = newAbstractPackage.addChildNode(JavaType.class, nodeName); newAbstractType.setQualifiedName(Strings.tryToRemoveBegginingFrom(JavaConstants.DEFAULT_PACKAGE + ".", packageName + "." + nodeName.replaceAll("[$]", "."))); newAbstractType.setSimpleName(nodeName); session.addLink(PackageType.class, newPackage, newType, false); session.addLink(AbstractTypeBind.class, newAbstractType, newType, false); nodesFromThisContext.put(packageName + nodeName, newType); if (logger.isInfoEnabled()) { logger.info("added class " + nodeType.getSimpleName() + " " + packageName + "." + nodeName); } return newType; }
From source file:org.openspotlight.bundle.language.java.resolver.JavaGraphNodeSupport.java
License:Open Source License
/** * Insert field data./*w w w . j av a2 s. c o m*/ * * @param field the field * @param fieldType the field type * @param access the access * @param isArray the is array * @param dimension the dimension * @throws Exception the exception */ private void insertFieldData(final JavaDataField field, final JavaType fieldType, final int access, final boolean isArray, final int dimension) throws Exception { final DataType fieldTypeLink = session.addLink(DataType.class, field, fieldType, false); fieldTypeLink.setArray(isArray); fieldTypeLink.setArrayDimension(dimension); final boolean isFieldPublic = (access & Opcodes.ACC_PUBLIC) != 0; final boolean isFieldPrivate = (access & Opcodes.ACC_PRIVATE) != 0; final boolean isFieldStatic = (access & Opcodes.ACC_STATIC) != 0; final boolean isFieldFinal = (access & Opcodes.ACC_FINAL) != 0; final boolean isFieldProtected = (access & Opcodes.ACC_PROTECTED) != 0; final boolean isFieldTransient = (access & Opcodes.ACC_TRANSIENT) != 0; final boolean isFieldVolatile = (access & Opcodes.ACC_VOLATILE) != 0; field.setPublic(isFieldPublic); field.setPrivate(isFieldPrivate); field.setStatic(isFieldStatic); field.setFinal(isFieldFinal); field.setProtected(isFieldProtected); field.setTransient(isFieldTransient); field.setVolatile(isFieldVolatile); }
From source file:org.openspotlight.bundle.language.java.resolver.JavaGraphNodeSupport.java
License:Open Source License
/** * Sets the method data.// ww w.ja v a 2s. c o m * * @param method the method * @param access the access */ private void setMethodData(final JavaMethod method, final int access) { final boolean isMethodPublic = (access & Opcodes.ACC_PUBLIC) != 0; final boolean isMethodPrivate = (access & Opcodes.ACC_PRIVATE) != 0; final boolean isMethodStatic = (access & Opcodes.ACC_STATIC) != 0; final boolean isMethodFinal = (access & Opcodes.ACC_FINAL) != 0; final boolean isMethodProtected = (access & Opcodes.ACC_PROTECTED) != 0; final boolean isMethodSynchronized = (access & Opcodes.ACC_SYNCHRONIZED) != 0; method.setPublic(isMethodPublic); method.setPrivate(isMethodPrivate); method.setStatic(isMethodStatic); method.setFinal(isMethodFinal); method.setProtected(isMethodProtected); method.setSynchronized(isMethodSynchronized); }
From source file:org.osjava.jardiff.Tools.java
License:Apache License
private static boolean isAccessIncompatible(int oldAccess, int newAccess) { if (has(newAccess, Opcodes.ACC_PUBLIC)) { return false; } else if (has(newAccess, Opcodes.ACC_PROTECTED)) { return has(oldAccess, Opcodes.ACC_PUBLIC); } else if (has(newAccess, Opcodes.ACC_PRIVATE)) { return not(oldAccess, Opcodes.ACC_PRIVATE); } else {/*from ww w . j a va 2s . c om*/ // new access is package, it is incompatible if old access was public or protected return has(oldAccess, Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED); } }
From source file:org.osjava.jardiff.Tools.java
License:Apache License
/** * Returns whether a field's newAccess is incompatible with oldAccess * following <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html">Java Language Specification, Java SE 7 Edition</a>: * <ul>//from www. java 2s. co m * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.9">13.4.7 Access to Members and Constructors</a><ul> * <li>Changing the declared access of a member or constructor to permit less access * <b>may break compatibility</b> with pre-existing binaries, causing a linkage error to be thrown when these binaries are resolved. * </li> * <li>The binary format is defined so that changing a member or constructor to be more accessible does not cause a * linkage error when a subclass (already) defines a method to have less access. * </li> * </ul></li> * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.9">13.4.9 final Fields and Constants</a><ul> * <li>If a field that was not declared final is changed to be declared final, * then it <b>can break compatibility</b> with pre-existing binaries that attempt to assign new values to the field.</li> * <li>Deleting the keyword final or changing the value to which a <i>non-final</i> field is initialized * <b>does not break compatibility</b> with existing binaries.</li> * <li>If a field is a constant variable (4.12.4), * then deleting the keyword final or changing its value * will <i>not break compatibility</i> with pre-existing binaries by causing them not to run, * but they will not see any new value for the usage of the field unless they are recompiled. * This is true even if the usage itself is not a compile-time constant expression (15.28). * Such changes <b>break functional backward compatibility</b>!</li> * </ul></li> * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.10">13.4.10 static Fields</a><ul> * <li>If a field that is not declared private was not declared static * and is changed to be declared static, or vice versa, * then a linkage error, specifically an IncompatibleClassChangeError, * will result if the field is used by a pre-existing binary which expected a field of the other kind. * Such changes <b>break backward compatibility</b>!</li> * </ul></li> * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.11">13.4.11. transient Fields </a><ul> * <li>Adding or deleting a transient modifier of a field * <b>does not break compatibility</b> with pre-existing binaries.</li> * </ul></li> * <li><a href="http://www.wsu.edu/UNIX_Systems/java/langspec-1.0/13.doc.html#45194">13.4.11 volatile Fields (JLS 1.0)</a><ul> * <li>If a field that is not declared private was not declared volatile * and is changed to be declared volatile, or vice versa, then a linkage time error, * specifically an IncompatibleClassChangeError, may result if the field is used * by a preexisting binary that expected a field of the opposite volatility. * Such changes <b>break backward compatibility</b>!</li> * </ul></li> * </ul> * * @param oldAccess * @param newAccess * @return */ public static boolean isFieldAccessChange(final int oldAccess, final int newAccess) { if (isAccessIncompatible(oldAccess, newAccess)) { return true; // 13.4.7 } if (not(oldAccess, Opcodes.ACC_FINAL) && has(newAccess, Opcodes.ACC_FINAL)) { return true; // 13.4.9 #1 } else { final int compatibleChanges = Opcodes.ACC_FINAL | // 13.4.9 #2 Opcodes.ACC_TRANSIENT; // 13.4.11 #1 final int accessPermissions = Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE; final int oldAccess2 = oldAccess & ~compatibleChanges & ~accessPermissions; final int newAccess2 = newAccess & ~compatibleChanges & ~accessPermissions; return oldAccess2 != newAccess2; } }
From source file:org.osjava.jardiff.Tools.java
License:Apache License
/** * Returns whether a method's newAccess is incompatible with oldAccess * following <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html">Java Language Specification, Java SE 7 Edition</a>: * <ul>// w w w . j ava 2s . c o m * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.9">13.4.7 Access to Members and Constructors</a><ul> * <li>Changing the declared access of a member or constructor to permit less access * <b>may break compatibility</b> with pre-existing binaries, causing a linkage error to be thrown when these binaries are resolved. * </li> * <li>The binary format is defined so that changing a member or constructor to be more accessible does not cause a * linkage error when a subclass (already) defines a method to have less access. * </li> * </ul></li> * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.16">13.4.16 abstract Methods</a><ul> * <li>Changing a method that is declared abstract to no longer be declared abstract * <b>does not break compatibility</b> with pre-existing binaries.</li> * <li>Changing a method that is not declared abstract to be declared abstract * <b>will break compatibility</b> with pre-existing binaries that previously invoked the method, causing an AbstractMethodError.</li> * </ul></li> * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.17">13.4.17 final</a><ul> * <li>Changing a method that is declared final to no longer be declared final * <b>does not break compatibility</b> with pre-existing binaries.</li> * <li>Changing an instance method that is not declared final to be declared final * <b>may break compatibility</b> with existing binaries that depend on the ability to override the method.</li> * <li>Changing a class (static) method that is not declared final to be declared final * <b>does not break compatibility</b> with existing binaries, because the method could not have been overridden.</li> * </ul></li> * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.18">13.4.18 native Methods</a><ul> * <li>Adding or deleting a native modifier of a method * <b>does not break compatibility</b> with pre-existing binaries.</li> * </ul></li> * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.19">13.4.19 static Methods</a><ul> * <li>If a method that is not declared private is also declared static (that is, a class method) * and is changed to not be declared static (that is, to an instance method), or vice versa, * then <i>compatibility with pre-existing binaries may be broken</i>, resulting in a linkage time error, * namely an IncompatibleClassChangeError, if these methods are used by the pre-existing binaries. * Such changes <b>break functional backward compatibility</b>!</li> * </ul></li> * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.20">13.4.20 synchronized Methods</a><ul> * <li>Adding or deleting a synchronized modifier of a method * <b>does not break compatibility</b> with pre-existing binaries.</li> * </ul></li> * <li><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.21">13.4.21 Method and Constructor Throws</a><ul> * <li>Changes to the throws clause of methods or constructors * <b>do not break compatibility</b> with pre-existing binaries; these clauses are checked only at compile time.</li> * </ul></li> * </ul> * * @param oldAccess * @param newAccess * @return */ public static boolean isMethodAccessChange(final int oldAccess, final int newAccess) { if (isAccessIncompatible(oldAccess, newAccess)) { return true; // 13.4.7 } if (not(oldAccess, Opcodes.ACC_ABSTRACT) && has(newAccess, Opcodes.ACC_ABSTRACT)) { return true; // 13.4.16 #2 } else if (not(oldAccess, Opcodes.ACC_FINAL) && not(oldAccess, Opcodes.ACC_STATIC) && has(newAccess, Opcodes.ACC_FINAL)) { return true; // 13.4.17 #2 excluding and #3 } else { final int compatibleChanges = Opcodes.ACC_ABSTRACT | // 13.4.16 #1 Opcodes.ACC_FINAL | // 13.4.17 #1 Opcodes.ACC_NATIVE | // 13.4.18 #1 Opcodes.ACC_SYNCHRONIZED; // 13.4.20 #1 final int accessPermissions = Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE; final int oldAccess2 = oldAccess & ~compatibleChanges & ~accessPermissions; final int newAccess2 = newAccess & ~compatibleChanges & ~accessPermissions; return oldAccess2 != newAccess2; } }
From source file:org.osjava.jardiff.ToolsTest.java
License:Apache License
@Test public void isClassAccessChange() { // A class can't become final. assertTrue(Tools.isClassAccessChange(0, Opcodes.ACC_FINAL)); assertTrue(Tools.isClassAccessChange(0, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL)); // ... but can become non-final. assertFalse(Tools.isClassAccessChange(Opcodes.ACC_FINAL, 0)); assertFalse(Tools.isClassAccessChange(Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); // No matter the final access, can't become protected or private or // package if it was public. assertTrue(Tools.isClassAccessChange(Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC, 0)); assertTrue(Tools.isClassAccessChange(Opcodes.ACC_PUBLIC, Opcodes.ACC_PROTECTED)); // A class can become concrete. assertFalse(Tools.isClassAccessChange(Opcodes.ACC_ABSTRACT, 0)); assertFalse(Tools.isClassAccessChange(Opcodes.ACC_ABSTRACT + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); assertFalse(Tools.isClassAccessChange(Opcodes.ACC_ABSTRACT + Opcodes.ACC_PROTECTED, Opcodes.ACC_PROTECTED)); // ...but can't become abstract assertTrue(Tools.isClassAccessChange(0, Opcodes.ACC_ABSTRACT)); assertTrue(Tools.isClassAccessChange(Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT)); assertTrue(Tools.isClassAccessChange(Opcodes.ACC_PROTECTED, Opcodes.ACC_PROTECTED + Opcodes.ACC_ABSTRACT)); }