/** * Invoked when current class classified as outer class of some inner class. * Adds inner class as member. */ private void defineInnerClass(String bytecodeName, int flags) { JavaSymbol.TypeJavaSymbol innerClass = getClassSymbol(bytecodeName, flags); innerClass.flags |= bytecodeCompleter.filterBytecodeFlags(flags); Preconditions.checkState(innerClass.owner == classSymbol, "Innerclass: " + innerClass.owner.getName() + " and classSymbol: " + classSymbol.getName() + " are not the same."); classSymbol.members.enter(innerClass); }
/** * Invoked when current class classified as outer class of some inner class. * Adds inner class as member. */ private void defineInnerClass(String bytecodeName, int flags) { JavaSymbol.TypeJavaSymbol innerClass = getClassSymbol(classSymbol, bytecodeName, flags); innerClass.flags |= bytecodeCompleter.filterBytecodeFlags(flags); Preconditions.checkState(innerClass.owner == classSymbol, "Innerclass: " + innerClass.owner.getName() + " and classSymbol: " + classSymbol.getName() + " are not the same."); classSymbol.members.enter(innerClass); }
@Override public void visit(int version, int flags, String name, @Nullable String signature, @Nullable String superName, @Nullable String[] interfaces) { Preconditions.checkState(name.endsWith(classSymbol.name), "Name : '" + name + "' should ends with " + classSymbol.name); Preconditions.checkState(!BytecodeCompleter.isSynthetic(flags), name + " is synthetic"); className = name; if (signature != null) { SignatureReader signatureReader = new SignatureReader(signature); ReadGenericSignature readGenericSignature = new ReadGenericSignature(); signatureReader.accept(readGenericSignature); ((JavaType.ClassJavaType) classSymbol.type).interfaces = readGenericSignature.interfaces(); } else { if (superName == null) { Preconditions.checkState("java/lang/Object".equals(className), "superName must be null only for java/lang/Object, but not for " + className); // TODO(Godin): what about interfaces and annotations } else { ((JavaType.ClassJavaType) classSymbol.type).supertype = getClassSymbol(superName).type; } ((JavaType.ClassJavaType) classSymbol.type).interfaces = getCompletedClassSymbolsType(interfaces); } //if class has already access flags set (inner class) then do not reset those. //The important access flags are the one defined in the outer class. if ((classSymbol.flags & Flags.ACCESS_FLAGS) != 0) { classSymbol.flags |= bytecodeCompleter.filterBytecodeFlags(flags & ~Flags.ACCESS_FLAGS); } else { classSymbol.flags |= bytecodeCompleter.filterBytecodeFlags(flags); } classSymbol.members = new Scope(classSymbol); }
@Override public void visit(int version, int flags, String name, @Nullable String signature, @Nullable String superName, @Nullable String[] interfaces) { Preconditions.checkState(name.endsWith(classSymbol.name), "Name : '" + name + "' should ends with " + classSymbol.name); Preconditions.checkState(!BytecodeCompleter.isSynthetic(flags), name + " is synthetic"); className = name; if (signature != null) { SignatureReader signatureReader = new SignatureReader(signature); signatureReader.accept(new TypeParameterDeclaration(classSymbol)); ReadGenericSignature readGenericSignature = new ReadGenericSignature(); signatureReader.accept(readGenericSignature); ((JavaType.ClassJavaType) classSymbol.type).interfaces = readGenericSignature.interfaces(); } else { if (superName == null) { Preconditions.checkState("java/lang/Object".equals(className), "superName must be null only for java/lang/Object, but not for " + className); // TODO(Godin): what about interfaces and annotations } else { ((JavaType.ClassJavaType) classSymbol.type).supertype = getClassSymbol(superName).type; } ((JavaType.ClassJavaType) classSymbol.type).interfaces = getCompletedClassSymbolsType(interfaces); } //if class has already access flags set (inner class) then do not reset those. //The important access flags are the one defined in the outer class. if ((classSymbol.flags & Flags.ACCESS_FLAGS) != 0) { classSymbol.flags |= bytecodeCompleter.filterBytecodeFlags(flags & ~Flags.ACCESS_FLAGS); } else { classSymbol.flags |= bytecodeCompleter.filterBytecodeFlags(flags); } classSymbol.members = new Scope(classSymbol); }
@Override public FieldVisitor visitField(int flags, String name, String desc, @Nullable String signature, @Nullable Object value) { Preconditions.checkNotNull(name); Preconditions.checkNotNull(desc); if (!BytecodeCompleter.isSynthetic(flags)) { //Flags from asm lib are defined in Opcodes class and map to flags defined in Flags class final JavaSymbol.VariableJavaSymbol symbol = new JavaSymbol.VariableJavaSymbol(bytecodeCompleter.filterBytecodeFlags(flags), name, convertAsmType(org.objectweb.asm.Type.getType(desc)), classSymbol); classSymbol.members.enter(symbol); if (signature != null) { ReadType typeReader = new ReadType(); new SignatureReader(signature).accept(typeReader); symbol.type = typeReader.typeRead; } // checks for annotations on the field return new BytecodeFieldVisitor(symbol, this); } return null; }
@Override public FieldVisitor visitField(int flags, String name, String desc, @Nullable String signature, @Nullable Object value) { Preconditions.checkNotNull(name); Preconditions.checkNotNull(desc); if (!BytecodeCompleter.isSynthetic(flags)) { //Flags from asm lib are defined in Opcodes class and map to flags defined in Flags class final JavaSymbol.VariableJavaSymbol symbol = new JavaSymbol.VariableJavaSymbol(bytecodeCompleter.filterBytecodeFlags(flags), name, convertAsmType(org.objectweb.asm.Type.getType(desc)), classSymbol); classSymbol.members.enter(symbol); if (signature != null) { ReadType typeReader = new ReadType(); new SignatureReader(signature).accept(typeReader); symbol.type = typeReader.typeRead; } // checks for annotations on the field return new BytecodeFieldVisitor(symbol, this); } return null; }
JavaSymbol.TypeJavaSymbol getClassSymbol(String bytecodeName, int flags) { String flatName = Convert.flatName(bytecodeName); JavaSymbol.TypeJavaSymbol symbol = classes.get(flatName); if (symbol == null) { String shortName = Convert.shortName(flatName); String packageName = Convert.packagePart(flatName); String enclosingClassName = Convert.enclosingClassName(shortName); if (StringUtils.isNotEmpty(enclosingClassName)) { //handle innerClasses symbol = new JavaSymbol.TypeJavaSymbol(filterBytecodeFlags(flags), Convert.innerClassName(shortName), getClassSymbol(Convert.fullName(packageName, enclosingClassName))); } else { symbol = new JavaSymbol.TypeJavaSymbol(filterBytecodeFlags(flags), shortName, enterPackage(packageName)); } symbol.members = new Scope(symbol); symbol.typeParameters = new Scope(symbol); // (Godin): IOException will happen without this condition in case of missing class: if (getClassLoader().getResource(Convert.bytecodeName(flatName) + ".class") != null) { symbol.completer = this; } else { LOG.error("Class not found: " + bytecodeName); ((JavaType.ClassJavaType) symbol.type).interfaces = ImmutableList.of(); ((JavaType.ClassJavaType) symbol.type).supertype = Symbols.unknownType; } classes.put(flatName, symbol); } return symbol; }
symbol = new JavaSymbol.TypeJavaSymbol(filterBytecodeFlags(flags), Convert.innerClassName(Convert.shortName(owner.getFullyQualifiedName()), shortName), owner); } else { symbol = new JavaSymbol.TypeJavaSymbol(filterBytecodeFlags(flags), shortName, enterPackage(packageName));
@Override public MethodVisitor visitMethod(int flags, String name, String desc, @Nullable String signature, @Nullable String[] exceptions) { Preconditions.checkNotNull(name); Preconditions.checkNotNull(desc); if (!BytecodeCompleter.isSynthetic(flags)) { Preconditions.checkState((flags & Opcodes.ACC_BRIDGE) == 0, "bridge method not marked as synthetic in class " + className); // TODO(Godin): according to JVMS 4.7.24 - parameter can be marked as synthetic JavaType.MethodJavaType type = new JavaType.MethodJavaType( convertAsmTypes(org.objectweb.asm.Type.getArgumentTypes(desc)), convertAsmType(org.objectweb.asm.Type.getReturnType(desc)), getCompletedClassSymbolsType(exceptions), classSymbol ); final JavaSymbol.MethodJavaSymbol methodSymbol = new JavaSymbol.MethodJavaSymbol(bytecodeCompleter.filterBytecodeFlags(flags), name, type, classSymbol); classSymbol.members.enter(methodSymbol); if (signature != null) { new SignatureReader(signature).accept(new ReadMethodSignature(methodSymbol)); } methodSymbol.parameters = new OrderedScope(methodSymbol); for (int i = 0; i < type.argTypes.size(); i += 1) { methodSymbol.parameters.enter(new JavaSymbol.VariableJavaSymbol(0, "arg" + i, methodSymbol)); } // checks for annotations on the method and its parameters return new BytecodeMethodVisitor(methodSymbol, this); } return null; }
@Override public MethodVisitor visitMethod(int flags, String name, String desc, @Nullable String signature, @Nullable String[] exceptions) { Preconditions.checkNotNull(name); Preconditions.checkNotNull(desc); if (!BytecodeCompleter.isSynthetic(flags)) { Preconditions.checkState((flags & Opcodes.ACC_BRIDGE) == 0, "bridge method not marked as synthetic in class " + className); // TODO(Godin): according to JVMS 4.7.24 - parameter can be marked as synthetic JavaType.MethodJavaType type = new JavaType.MethodJavaType( convertAsmTypes(org.objectweb.asm.Type.getArgumentTypes(desc)), convertAsmType(org.objectweb.asm.Type.getReturnType(desc)), getCompletedClassSymbolsType(exceptions), classSymbol ); final JavaSymbol.MethodJavaSymbol methodSymbol = new JavaSymbol.MethodJavaSymbol(bytecodeCompleter.filterBytecodeFlags(flags), name, type, classSymbol); classSymbol.members.enter(methodSymbol); if (signature != null) { SignatureReader signatureReader = new SignatureReader(signature); signatureReader.accept(new TypeParameterDeclaration(methodSymbol)); signatureReader.accept(new ReadMethodSignature(methodSymbol)); } methodSymbol.parameters = new Scope(methodSymbol); for (int i = 0; i < type.argTypes.size(); i += 1) { methodSymbol.parameters.enter(new JavaSymbol.VariableJavaSymbol(0, "arg" + i, methodSymbol)); } // checks for annotations on the method and its parameters return new BytecodeMethodVisitor(methodSymbol, this); } return null; }