From d16802af450aa32e252e4222fecca5c637fd8228 Mon Sep 17 00:00:00 2001 From: Vincent Rasquier Date: Wed, 13 Dec 2017 18:50:42 +0100 Subject: [PATCH] Add module reading and some fixes --- ...tation-visitor.go => annotationvisitor.go} | 0 asm/{class-reader.go => classreader.go} | 94 ++++++++++++++++++- asm/{class-visitor.go => classvisitor.go} | 4 +- asm/fieldvisitor.go | 11 +++ asm/{method-visitor.go => methodvisitor.go} | 0 asm/modulevisitor.go | 16 ++++ asm/{type-reference.go => typereference.go} | 0 event-visitor.go | 8 +- main.go | 4 +- 9 files changed, 128 insertions(+), 9 deletions(-) rename asm/{annotation-visitor.go => annotationvisitor.go} (100%) rename asm/{class-reader.go => classreader.go} (89%) rename asm/{class-visitor.go => classvisitor.go} (89%) create mode 100644 asm/fieldvisitor.go rename asm/{method-visitor.go => methodvisitor.go} (100%) create mode 100644 asm/modulevisitor.go rename asm/{type-reference.go => typereference.go} (100%) diff --git a/asm/annotation-visitor.go b/asm/annotationvisitor.go similarity index 100% rename from asm/annotation-visitor.go rename to asm/annotationvisitor.go diff --git a/asm/class-reader.go b/asm/classreader.go similarity index 89% rename from asm/class-reader.go rename to asm/classreader.go index bbe327a..9eb1396 100644 --- a/asm/class-reader.go +++ b/asm/classreader.go @@ -365,7 +365,99 @@ func (c ClassReader) AcceptB(classVisitor ClassVisitor, attributePrototypes []At // ---------------------------------------------------------------------------------------------- func (c ClassReader) readModule(classVisitor ClassVisitor, context *Context, moduleOffset int, modulePackagesOffset int, moduleMainClass string) { - //TODO + buffer := context.charBuffer + currentOffset := moduleOffset + moduleName := c.readModuleB(currentOffset, buffer) + moduleFlags := c.readUnsignedShort(currentOffset + 2) + moduleVersion := c.readUTF8(currentOffset+4, buffer) + currentOffset += 6 + moduleVisitor := classVisitor.VisitModule(moduleName, moduleFlags, moduleVersion) + if moduleVisitor == nil { + return + } + + if modulePackagesOffset != 0 { + packageCount := c.readUnsignedShort(modulePackagesOffset) + currentPackageOffset := modulePackagesOffset + 2 + for packageCount > 0 { + moduleVisitor.VisitPackage(c.readPackage(currentPackageOffset, buffer)) + currentPackageOffset += 2 + packageCount-- + } + } + + requiresCount := c.readUnsignedShort(currentOffset) + currentOffset += 2 + for requiresCount > 0 { + requires := c.readModuleB(currentOffset, buffer) + requiresFlags := c.readUnsignedShort(currentOffset + 2) + requiresVersion := c.readUTF8(currentOffset+4, buffer) + currentOffset += 6 + moduleVisitor.VisitRequire(requires, requiresFlags, requiresVersion) + requiresCount-- + } + + exportsCount := c.readUnsignedShort(currentOffset) + currentOffset += 2 + for exportsCount > 0 { + exports := c.readPackage(currentOffset, buffer) + exportsFlags := c.readUnsignedShort(currentOffset + 2) + exportsToCount := c.readUnsignedShort(currentOffset + 4) + currentOffset += 6 + var exportsTo []string + if exportsToCount != 0 { + exportsTo = make([]string, exportsToCount) + for i := 0; i < exportsToCount; i++ { + exportsTo[i] = c.readModuleB(currentOffset, buffer) + currentOffset += 2 + } + } + moduleVisitor.VisitExport(exports, exportsFlags, exportsTo...) + exportsCount-- + } + + opensCount := c.readUnsignedShort(currentOffset) + currentOffset += 2 + for opensCount > 0 { + opens := c.readPackage(currentOffset, buffer) + opensFlags := c.readUnsignedShort(currentOffset + 2) + opensToCount := c.readUnsignedShort(currentOffset + 4) + currentOffset += 6 + var opensTo []string + if opensToCount != 0 { + opensTo = make([]string, opensToCount) + for i := 0; i < opensToCount; i++ { + opensTo[i] = c.readModuleB(currentOffset, buffer) + currentOffset += 2 + } + } + moduleVisitor.VisitOpen(opens, opensFlags, opensTo...) + } + + usesCount := c.readUnsignedShort(currentOffset) + currentOffset += 2 + for usesCount > 0 { + moduleVisitor.VisitUse(c.readClass(currentOffset, buffer)) + currentOffset += 2 + usesCount-- + } + + providesCount := c.readUnsignedShort(currentOffset) + currentOffset += 2 + for providesCount > 0 { + provides := c.readClass(currentOffset, buffer) + providesWithCount := c.readUnsignedShort(currentOffset + 2) + currentOffset += 4 + providesWith := make([]string, providesWithCount) + for i := 0; i < providesWithCount; i++ { + providesWith[i] = c.readClass(currentOffset, buffer) + currentOffset += 2 + } + moduleVisitor.VisitProvide(provides, providesWith...) + providesCount-- + } + + moduleVisitor.VisitEnd() } func (c ClassReader) readField(classVisitor ClassVisitor, context *Context, fieldInfoOffset int) int { diff --git a/asm/class-visitor.go b/asm/classvisitor.go similarity index 89% rename from asm/class-visitor.go rename to asm/classvisitor.go index 28ba428..3c19e5f 100644 --- a/asm/class-visitor.go +++ b/asm/classvisitor.go @@ -7,13 +7,13 @@ package asm type ClassVisitor interface { Visit(version, access int, name, signature, superName string, interfaces []string) VisitSource(source, debug string) - VisitModule(name string, access, version int) //should return modulevisitor + VisitModule(name string, access int, version string) ModuleVisitor VisitOuterClass(owner, name, descriptor string) VisitAnnotation(descriptor string, visible bool) AnnotationVisitor VisitTypeAnnotation(typeRef, typePath int, descriptor string, visible bool) AnnotationVisitor //typePath : TypePath VisitAttribute(attribute *Attribute) VisitInnerClass(name, outerName, innerName string, access int) - VisitField(access int, name, descriptor, signature string, value interface{}) //should return FieldVisitor + VisitField(access int, name, descriptor, signature string, value interface{}) FieldVisitor VisitMethod(access int, name, descriptor, signature string, exceptions []string) MethodVisitor VisitEnd() } diff --git a/asm/fieldvisitor.go b/asm/fieldvisitor.go new file mode 100644 index 0000000..5f3262a --- /dev/null +++ b/asm/fieldvisitor.go @@ -0,0 +1,11 @@ +package asm + +// FieldVisitor a visitor to visit a Java field. The methods of this class must be called in the following order: +// ( visitAnnotation | visitTypeAnnotation | visitAttribute )* +// visitEnd. +type FieldVisitor interface { + VisitAnnotation(descriptor string, visible bool) AnnotationVisitor + VisitTypeAnnotation(typeRef int, typePath interface{}, descriptor string, visible bool) AnnotationVisitor //TypePath + VisitAttribute(attribute *Attribute) + VisitEnd() +} diff --git a/asm/method-visitor.go b/asm/methodvisitor.go similarity index 100% rename from asm/method-visitor.go rename to asm/methodvisitor.go diff --git a/asm/modulevisitor.go b/asm/modulevisitor.go new file mode 100644 index 0000000..4f1223d --- /dev/null +++ b/asm/modulevisitor.go @@ -0,0 +1,16 @@ +package asm + +// ModuleVisitor a visitor to visit a Java module. The methods of this class must be called in the following +// order: visitMainClass | ( visitPackage | visitRequire | +// visitExport | visitOpen | visitUse | visitProvide )* +// visitEnd. +type ModuleVisitor interface { + VisitMainClass(mainClass string) + VisitPackage(packaze string) + VisitRequire(module string, access int, version string) + VisitExport(packaze string, access int, modules ...string) + VisitOpen(packaze string, access int, modules ...string) + VisitUse(service string) + VisitProvide(service string, providers ...string) + VisitEnd() +} diff --git a/asm/type-reference.go b/asm/typereference.go similarity index 100% rename from asm/type-reference.go rename to asm/typereference.go diff --git a/event-visitor.go b/event-visitor.go index dea050a..e0a57f3 100644 --- a/event-visitor.go +++ b/event-visitor.go @@ -19,8 +19,8 @@ func (e EventVisitor) VisitSource(source, debug string) { } -func (e EventVisitor) VisitModule(name string, access, version int) { - +func (e EventVisitor) VisitModule(name string, access int, version string) asm.ModuleVisitor { + return nil } func (e EventVisitor) VisitOuterClass(owner, name, descriptor string) { @@ -43,8 +43,8 @@ func (e EventVisitor) VisitInnerClass(name, outerName, innerName string, access } -func (e EventVisitor) VisitField(access int, name, descriptor, signature string, value interface{}) { - +func (e EventVisitor) VisitField(access int, name, descriptor, signature string, value interface{}) asm.FieldVisitor { + return nil } func (e EventVisitor) VisitMethod(access int, name, descriptor, signature string, exceptions []string) asm.MethodVisitor { diff --git a/main.go b/main.go index e161517..1ea6fc9 100644 --- a/main.go +++ b/main.go @@ -20,13 +20,13 @@ func main() { os.Exit(1) } - r, err := asm.NewClassReader(bytes) + reader, err := asm.NewClassReader(bytes) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } - r.Accept(&EventVisitor{ + reader.Accept(&EventVisitor{ OnVisit: []func(version, access int, name, signature, superName string, interfaces []string){ func(version, access int, name, signature, superName string, interfaces []string) { fmt.Println(name, signature, superName, interfaces)