From 2d141a58c68d7039a645db1452340a5b59ca3946 Mon Sep 17 00:00:00 2001 From: REghZy Date: Thu, 21 Jul 2022 18:35:59 +0100 Subject: [PATCH 1/8] Converted code to .NET Standard 2.0 --- JavaAsm/AttributeNode.cs | 16 +- JavaAsm/ClassAccessModifiers.cs | 33 +- JavaAsm/ClassName.cs | 8 +- JavaAsm/ClassNode.cs | 98 ++-- JavaAsm/Commons/MethodHelper.cs | 239 ++++---- .../Annotation/AnnotationNode.cs | 18 +- .../Annotation/ElementValue.cs | 38 +- .../AnnotationDefaultAttribute.cs | 4 +- .../BootstrapMethodsAttribute.cs | 141 +++-- JavaAsm/CustomAttributes/CodeAttribute.cs | 53 +- .../ConstantValueAttribute.cs | 50 +- .../EnclosingMethodAttribute.cs | 20 +- .../CustomAttributes/ExceptionsAttribute.cs | 18 +- .../CustomAttributes/InnerClassesAttribute.cs | 24 +- .../LineNumberTableAttribute.cs | 16 +- .../LocalVariableTableAttribute.cs | 16 +- .../LocalVariableTypeTableAttribute.cs | 18 +- .../MethodParametersAttribute.cs | 16 +- .../RuntimeInvisibleAnnotationsAttribute.cs | 16 +- ...eInvisibleParameterAnnotationsAttribute.cs | 24 +- ...untimeInvisibleTypeAnnotationsAttribute.cs | 16 +- .../RuntimeVisibleAnnotationsAttribute.cs | 16 +- ...imeVisibleParameterAnnotationsAttribute.cs | 26 +- .../RuntimeVisibleTypeAnnotationsAttribute.cs | 22 +- .../CustomAttributes/SignatureAttribute.cs | 4 +- .../SourceDebugExtensionAttribute.cs | 2 +- .../CustomAttributes/SourceFileAttribute.cs | 6 +- .../StackMapTableAttribute.cs | 77 ++- .../TypeAnnotation/CatchTarget.cs | 4 +- .../TypeAnnotation/FormalParameterTarget.cs | 4 +- .../TypeAnnotation/LocalvarTarget.cs | 16 +- .../TypeAnnotation/OffsetTarget.cs | 4 +- .../TypeAnnotation/SupertypeTarget.cs | 4 +- .../TypeAnnotation/TargetType.cs | 2 +- .../TypeAnnotation/ThrowsTarget.cs | 4 +- .../TypeAnnotation/TypeAnnotationNode.cs | 144 +++-- .../TypeAnnotation/TypeArgumentTarget.cs | 8 +- .../TypeParameterBoundTarget.cs | 8 +- .../TypeAnnotation/TypeParameterTarget.cs | 4 +- .../TypeAnnotation/TypePath.cs | 16 +- JavaAsm/FieldNode.cs | 62 +-- JavaAsm/Helpers/Extensions.cs | 66 +-- JavaAsm/Helpers/ModifiedUtf8Helper.cs | 18 +- JavaAsm/Helpers/ReadCountStream.cs | 20 +- JavaAsm/IO/ClassFile.cs | 63 +-- JavaAsm/IO/ConstantPool.cs | 109 ++-- JavaAsm/IO/ConstantPoolEntries/ClassEntry.cs | 14 +- JavaAsm/IO/ConstantPoolEntries/DoubleEntry.cs | 10 +- JavaAsm/IO/ConstantPoolEntries/FloatEntry.cs | 48 +- .../IO/ConstantPoolEntries/IntegerEntry.cs | 10 +- .../ConstantPoolEntries/InvokeDynamicEntry.cs | 20 +- JavaAsm/IO/ConstantPoolEntries/LongEntry.cs | 10 +- .../ConstantPoolEntries/MethodHandleEntry.cs | 32 +- .../IO/ConstantPoolEntries/MethodTypeEntry.cs | 14 +- .../ConstantPoolEntries/NameAndTypeEntry.cs | 24 +- .../IO/ConstantPoolEntries/ReferenceEntry.cs | 24 +- JavaAsm/IO/ConstantPoolEntries/StringEntry.cs | 14 +- JavaAsm/IO/ConstantPoolEntries/Utf8Entry.cs | 16 +- JavaAsm/Instructions/InstructionList.cs | 48 +- .../Instructions/InstructionListConverter.cs | 527 +++++++++--------- .../Instructions/Types/FieldInstruction.cs | 4 +- .../Types/IncrementInstruction.cs | 2 +- .../Types/IntegerPushInstruction.cs | 4 +- .../Types/InvokeDynamicInstruction.cs | 43 +- JavaAsm/Instructions/Types/JumpInstruction.cs | 6 +- JavaAsm/Instructions/Types/Label.cs | 4 +- JavaAsm/Instructions/Types/LdcInstruction.cs | 6 +- JavaAsm/Instructions/Types/LineNumber.cs | 2 +- .../Instructions/Types/MethodInstruction.cs | 4 +- .../Types/MultiANewArrayInstruction.cs | 2 +- .../Instructions/Types/NewArrayInstruction.cs | 2 +- .../Instructions/Types/SimpleInstruction.cs | 26 +- JavaAsm/Instructions/Types/StackMapFrame.cs | 2 +- JavaAsm/Instructions/Types/TypeInstruction.cs | 4 +- .../Instructions/Types/VariableInstruction.cs | 4 +- JavaAsm/JavaAsm.csproj | 10 +- JavaAsm/MethodDescriptor.cs | 22 +- JavaAsm/MethodNode.cs | 78 +-- JavaAsm/TypeDescriptor.cs | 119 ++-- 79 files changed, 1354 insertions(+), 1392 deletions(-) diff --git a/JavaAsm/AttributeNode.cs b/JavaAsm/AttributeNode.cs index 7dee115..bb71818 100644 --- a/JavaAsm/AttributeNode.cs +++ b/JavaAsm/AttributeNode.cs @@ -89,22 +89,22 @@ public class AttributeNode internal void Parse(Stream stream, AttributeScope scope, ClassReaderState readerState) { - var dataLength = Binary.BigEndian.ReadUInt32(stream); - var data = stream.ReadBytes(dataLength); + uint dataLength = Binary.BigEndian.ReadUInt32(stream); + byte[] data = stream.ReadBytes(dataLength); try { - if (!predefinedAttributes.ContainsKey((Name, scope))) - throw new ArgumentException($"Attribute {Name} in {scope} not found"); - var readWriteCounter = new ReadWriteCountStream(new MemoryStream(data)); - ParsedAttribute = predefinedAttributes[(Name, scope)].Parse(readWriteCounter, dataLength, readerState, scope); + if (!predefinedAttributes.ContainsKey((this.Name, scope))) + throw new ArgumentException($"Attribute {this.Name} in {scope} not found"); + ReadWriteCountStream readWriteCounter = new ReadWriteCountStream(new MemoryStream(data)); + this.ParsedAttribute = predefinedAttributes[(this.Name, scope)].Parse(readWriteCounter, dataLength, readerState, scope); if (readWriteCounter.ReadBytes != dataLength) throw new ArgumentOutOfRangeException(nameof(dataLength), - $"Wrong data length of attribute {Name} in {scope}: Given {dataLength}, Read: {readWriteCounter.ReadBytes}"); + $"Wrong data length of attribute {this.Name} in {scope}: Given {dataLength}, Read: {readWriteCounter.ReadBytes}"); } catch { - Data = data; + this.Data = data; } } diff --git a/JavaAsm/ClassAccessModifiers.cs b/JavaAsm/ClassAccessModifiers.cs index 745606d..7852ce8 100644 --- a/JavaAsm/ClassAccessModifiers.cs +++ b/JavaAsm/ClassAccessModifiers.cs @@ -1,11 +1,9 @@ using System; using System.Linq; -namespace JavaAsm -{ +namespace JavaAsm { [Flags] - public enum ClassAccessModifiers : ushort - { + public enum ClassAccessModifiers : ushort { Public = 0x0001, Protected = 0x0004, Private = 0x0002, @@ -21,8 +19,7 @@ public enum ClassAccessModifiers : ushort } [Flags] - public enum MethodAccessModifiers : ushort - { + public enum MethodAccessModifiers : ushort { Public = 0x0001, Protected = 0x0004, Private = 0x0002, @@ -38,8 +35,7 @@ public enum MethodAccessModifiers : ushort } [Flags] - public enum FieldAccessModifiers : ushort - { + public enum FieldAccessModifiers : ushort { Public = 0x0001, Protected = 0x0004, Private = 0x0002, @@ -52,25 +48,10 @@ public enum FieldAccessModifiers : ushort public static class AccessModifiersExtensions { - public static string ToString(ClassAccessModifiers accessModifiers) - { - return string.Join(' ', - Enum.GetValues(typeof(ClassAccessModifiers)).OfType().Where(x => accessModifiers.HasFlag(x)) - .Select(x => x.ToString().ToLower())); - } + public static string ToString(ClassAccessModifiers accessModifiers) => string.Join(" ", Enum.GetValues(typeof(ClassAccessModifiers)).OfType().Where(x => accessModifiers.HasFlag(x)).Select(x => x.ToString().ToLower())); - public static string ToString(MethodAccessModifiers accessModifiers) - { - return string.Join(' ', - Enum.GetValues(typeof(MethodAccessModifiers)).OfType().Where(x => accessModifiers.HasFlag(x)) - .Select(x => x.ToString().ToLower())); - } + public static string ToString(MethodAccessModifiers accessModifiers) => string.Join(" ", Enum.GetValues(typeof(MethodAccessModifiers)).OfType().Where(x => accessModifiers.HasFlag(x)).Select(x => x.ToString().ToLower())); - public static string ToString(FieldAccessModifiers accessModifiers) - { - return string.Join(' ', - Enum.GetValues(typeof(FieldAccessModifiers)).OfType().Where(x => accessModifiers.HasFlag(x)) - .Select(x => x.ToString().ToLower())); - } + public static string ToString(FieldAccessModifiers accessModifiers) => string.Join(" ", Enum.GetValues(typeof(FieldAccessModifiers)).OfType().Where(x => accessModifiers.HasFlag(x)).Select(x => x.ToString().ToLower())); } } \ No newline at end of file diff --git a/JavaAsm/ClassName.cs b/JavaAsm/ClassName.cs index 35be692..37a5ab1 100644 --- a/JavaAsm/ClassName.cs +++ b/JavaAsm/ClassName.cs @@ -8,17 +8,17 @@ public class ClassName public ClassName(string name) { - Name = name ?? throw new ArgumentNullException(nameof(name)); + this.Name = name ?? throw new ArgumentNullException(nameof(name)); } public override string ToString() { - return Name.Replace("/", "."); + return this.Name.Replace("/", "."); } private bool Equals(ClassName other) { - return Name == other.Name; + return this.Name == other.Name; } public override bool Equals(object obj) @@ -30,7 +30,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return Name.GetHashCode(); + return this.Name.GetHashCode(); } } } \ No newline at end of file diff --git a/JavaAsm/ClassNode.cs b/JavaAsm/ClassNode.cs index b0b892c..55f041d 100644 --- a/JavaAsm/ClassNode.cs +++ b/JavaAsm/ClassNode.cs @@ -49,168 +49,168 @@ public class ClassNode private AttributeNode GetAttribute(string name) { - var attribute = Attributes.FirstOrDefault(a => a.Name == name); + AttributeNode attribute = this.Attributes.FirstOrDefault(a => a.Name == name); if (attribute != null) - Attributes.Remove(attribute); + this.Attributes.Remove(attribute); return attribute; } internal void Parse(ClassReaderState readerState) { - SourceFile = (GetAttribute(PredefinedAttributeNames.SourceFile)?.ParsedAttribute as SourceFileAttribute)?.Value; - SourceDebugExtension = (GetAttribute(PredefinedAttributeNames.SourceDebugExtension)?.ParsedAttribute as SourceFileAttribute)?.Value; - Signature = (GetAttribute(PredefinedAttributeNames.Signature)?.ParsedAttribute as SignatureAttribute)?.Value; + this.SourceFile = (GetAttribute(PredefinedAttributeNames.SourceFile)?.ParsedAttribute as SourceFileAttribute)?.Value; + this.SourceDebugExtension = (GetAttribute(PredefinedAttributeNames.SourceDebugExtension)?.ParsedAttribute as SourceFileAttribute)?.Value; + this.Signature = (GetAttribute(PredefinedAttributeNames.Signature)?.ParsedAttribute as SignatureAttribute)?.Value; { - var attribute = GetAttribute(PredefinedAttributeNames.RuntimeInvisibleAnnotations); + AttributeNode attribute = GetAttribute(PredefinedAttributeNames.RuntimeInvisibleAnnotations); if (attribute != null) - InvisibleAnnotations = (attribute.ParsedAttribute as RuntimeInvisibleAnnotationsAttribute)?.Annotations; + this.InvisibleAnnotations = (attribute.ParsedAttribute as RuntimeInvisibleAnnotationsAttribute)?.Annotations; } { - var attribute = GetAttribute(PredefinedAttributeNames.RuntimeVisibleAnnotations); + AttributeNode attribute = GetAttribute(PredefinedAttributeNames.RuntimeVisibleAnnotations); if (attribute != null) - VisibleAnnotations = (attribute.ParsedAttribute as RuntimeVisibleAnnotationsAttribute)?.Annotations; + this.VisibleAnnotations = (attribute.ParsedAttribute as RuntimeVisibleAnnotationsAttribute)?.Annotations; } - IsDeprecated = GetAttribute(PredefinedAttributeNames.Deprecated)?.ParsedAttribute != null; - EnclosingMethod = GetAttribute(PredefinedAttributeNames.EnclosingMethod)?.ParsedAttribute as EnclosingMethodAttribute; + this.IsDeprecated = GetAttribute(PredefinedAttributeNames.Deprecated)?.ParsedAttribute != null; + this.EnclosingMethod = GetAttribute(PredefinedAttributeNames.EnclosingMethod)?.ParsedAttribute as EnclosingMethodAttribute; { - var attribute = GetAttribute(PredefinedAttributeNames.InnerClasses); + AttributeNode attribute = GetAttribute(PredefinedAttributeNames.InnerClasses); if (attribute != null) - InnerClasses = (attribute.ParsedAttribute as InnerClassesAttribute)?.Classes; + this.InnerClasses = (attribute.ParsedAttribute as InnerClassesAttribute)?.Classes; } - foreach (var method in Methods) + foreach (MethodNode method in this.Methods) method.Parse(readerState); - foreach (var field in Fields) + foreach (FieldNode field in this.Fields) field.Parse(readerState); } internal void Save(ClassWriterState writerState) { - if (SourceFile != null) + if (this.SourceFile != null) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.SourceFile)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.SourceFile)) throw new Exception( $"{PredefinedAttributeNames.SourceFile} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.SourceFile, ParsedAttribute = new SourceFileAttribute { - Value = SourceFile + Value = this.SourceFile } }); } - if (SourceDebugExtension != null) + if (this.SourceDebugExtension != null) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.SourceDebugExtension)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.SourceDebugExtension)) throw new Exception( $"{PredefinedAttributeNames.SourceDebugExtension} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.SourceDebugExtension, ParsedAttribute = new SourceDebugExtensionAttribute { - Value = SourceDebugExtension + Value = this.SourceDebugExtension } }); } - if (Signature != null) + if (this.Signature != null) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.Signature)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Signature)) throw new Exception( $"{PredefinedAttributeNames.Signature} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Signature, ParsedAttribute = new SignatureAttribute { - Value = Signature + Value = this.Signature } }); } - if (InvisibleAnnotations != null && InvisibleAnnotations.Count > 0) + if (this.InvisibleAnnotations != null && this.InvisibleAnnotations.Count > 0) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeInvisibleAnnotations)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeInvisibleAnnotations)) throw new Exception( $"{PredefinedAttributeNames.RuntimeInvisibleAnnotations} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeInvisibleAnnotations, ParsedAttribute = new RuntimeInvisibleAnnotationsAttribute { - Annotations = InvisibleAnnotations + Annotations = this.InvisibleAnnotations } }); } - if (VisibleAnnotations != null && VisibleAnnotations.Count > 0) + if (this.VisibleAnnotations != null && this.VisibleAnnotations.Count > 0) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeVisibleAnnotations)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeVisibleAnnotations)) throw new Exception( $"{PredefinedAttributeNames.RuntimeVisibleAnnotations} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeVisibleAnnotations, ParsedAttribute = new RuntimeVisibleAnnotationsAttribute { - Annotations = VisibleAnnotations + Annotations = this.VisibleAnnotations } }); } - if (IsDeprecated) + if (this.IsDeprecated) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.Deprecated)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Deprecated)) throw new Exception( $"{PredefinedAttributeNames.Deprecated} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Deprecated, ParsedAttribute = new DeprecatedAttribute() }); } - if (EnclosingMethod != null) + if (this.EnclosingMethod != null) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.EnclosingMethod)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.EnclosingMethod)) throw new Exception( $"{PredefinedAttributeNames.EnclosingMethod} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.EnclosingMethod, - ParsedAttribute = EnclosingMethod + ParsedAttribute = this.EnclosingMethod }); } - if (InnerClasses != null) + if (this.InnerClasses != null) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.InnerClasses)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.InnerClasses)) throw new Exception( $"{PredefinedAttributeNames.InnerClasses} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.InnerClasses, ParsedAttribute = new InnerClassesAttribute { - Classes = InnerClasses + Classes = this.InnerClasses } }); } - foreach (var method in Methods) + foreach (MethodNode method in this.Methods) method.Save(writerState); - foreach (var field in Fields) + foreach (FieldNode field in this.Fields) field.Save(writerState); } public override string ToString() { - return $"{AccessModifiersExtensions.ToString(Access)} {Name}"; + return $"{AccessModifiersExtensions.ToString(this.Access)} {this.Name}"; } } } \ No newline at end of file diff --git a/JavaAsm/Commons/MethodHelper.cs b/JavaAsm/Commons/MethodHelper.cs index c5c4c96..7a96cab 100644 --- a/JavaAsm/Commons/MethodHelper.cs +++ b/JavaAsm/Commons/MethodHelper.cs @@ -5,52 +5,47 @@ using JavaAsm.Instructions; using JavaAsm.Instructions.Types; -namespace JavaAsm.Commons -{ +namespace JavaAsm.Commons { /// /// Helper class for different operations with methods (computing sizes, frames, etc) /// - public static class MethodHelper - { + public static class MethodHelper { /// /// Computers max number of locals and stack /// /// Method to compute for /// ValueTuple of max number of locals and stack - public static (ushort MaxLocals, ushort MaxStack) ComputeMaxStackAndLocals(MethodNode methodNode) - { + public static (ushort MaxLocals, ushort MaxStack) ComputeMaxStackAndLocals(MethodNode methodNode) { if (methodNode.Instructions == null || methodNode.Access.HasFlag(MethodAccessModifiers.Native) || methodNode.Access.HasFlag(MethodAccessModifiers.Abstract)) throw new ArgumentOutOfRangeException(nameof(methodNode), "Can't compute stack and locals for native or abstract method"); - var maxLocalIndex = Math.Max(methodNode.Instructions.Any(x => x is VariableInstruction) ? - methodNode.Instructions.Where(x => x is VariableInstruction).Max(x => ((VariableInstruction) x).VariableIndex + - (x.Opcode.In(Opcode.LLOAD, Opcode.LSTORE, Opcode.DLOAD, Opcode.DSTORE) ? 1 : 0)) + 1 : 0, - methodNode.Descriptor.ArgumentTypes.Sum(x => x.SizeOnStack) + (methodNode.Access.HasFlag(MethodAccessModifiers.Static) ? 0 : 1)); + int maxLocalIndex = Math.Max(methodNode.Instructions.Any(x => x is VariableInstruction) + ? methodNode.Instructions.Where(x => x is VariableInstruction).Max(x => ((VariableInstruction) x).VariableIndex + + (x.Opcode.In(Opcode.LLOAD, Opcode.LSTORE, Opcode.DLOAD, Opcode.DSTORE) ? 1 : 0)) + 1 + : 0, + methodNode.Descriptor.ArgumentTypes.Sum(x => x.SizeOnStack) + (methodNode.Access.HasFlag(MethodAccessModifiers.Static) ? 0 : 1)); if (maxLocalIndex > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(maxLocalIndex), $"Max local index is larger that maximum possible amount: {maxLocalIndex} > {ushort.MaxValue}"); - var maxLocals = (ushort) maxLocalIndex; + ushort maxLocals = (ushort) maxLocalIndex; - var queueToCompute = new Queue(); + Queue queueToCompute = new Queue(); queueToCompute.Enqueue(methodNode.Instructions.First); - var stackSizes = new Dictionary - { - { methodNode.Instructions.First, 0 } + Dictionary stackSizes = new Dictionary { + {methodNode.Instructions.First, 0} }; - foreach (var tryCatchBlock in methodNode.TryCatches) - { + foreach (TryCatchNode tryCatchBlock in methodNode.TryCatches) { if (tryCatchBlock.Handler.OwnerList != methodNode.Instructions) throw new Exception("TryCatch block handler label does not belongs to methodNode's instructions list"); - if (stackSizes.TryAdd(tryCatchBlock.Handler, 1)) + if (stackSizes.TryAdd(tryCatchBlock.Handler, 1)) queueToCompute.Enqueue(tryCatchBlock.Handler); } - static void CheckStackSizeAndThrow(int stackSize) - { + void CheckStackSizeAndThrow(int stackSize) { if (stackSize < 0) throw new ArgumentOutOfRangeException(nameof(stackSize), $"Stack underflow: {stackSize} < {ushort.MinValue}"); @@ -59,8 +54,7 @@ static void CheckStackSizeAndThrow(int stackSize) $"Stack overflow: {stackSize} > {ushort.MaxValue}"); } - void EnqueueInstruction(Instruction instruction, int newStackSize) - { + void EnqueueInstruction(Instruction instruction, int newStackSize) { CheckStackSizeAndThrow(newStackSize); if (stackSizes.TryAdd(instruction, (ushort) newStackSize)) queueToCompute.Enqueue(instruction); @@ -68,15 +62,12 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) throw new Exception($"Stack size difference on instruction {instruction}"); } - while (queueToCompute.Any()) - { - var currentInstruction = queueToCompute.Dequeue(); - var newStackSize = (int) stackSizes[currentInstruction]; - switch (currentInstruction) - { + while (queueToCompute.Any()) { + Instruction currentInstruction = queueToCompute.Dequeue(); + int newStackSize = stackSizes[currentInstruction]; + switch (currentInstruction) { case FieldInstruction fieldInstruction: - if (fieldInstruction.Opcode.In(Opcode.GETFIELD, Opcode.PUTFIELD)) - { + if (fieldInstruction.Opcode.In(Opcode.GETFIELD, Opcode.PUTFIELD)) { newStackSize--; CheckStackSizeAndThrow(newStackSize); } @@ -96,8 +87,7 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) break; case JumpInstruction jumpInstruction: // ReSharper disable once SwitchStatementMissingSomeCases - switch (jumpInstruction.Opcode) - { + switch (jumpInstruction.Opcode) { case Opcode.IFEQ: case Opcode.IFNE: case Opcode.IFLT: @@ -127,9 +117,9 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) case Opcode.GOTO: EnqueueInstruction(jumpInstruction.Target, newStackSize); continue; - default: - throw new ArgumentOutOfRangeException(nameof(jumpInstruction.Opcode)); + default: throw new ArgumentOutOfRangeException(nameof(jumpInstruction.Opcode)); } + break; case LdcInstruction ldcInstruction: newStackSize += ldcInstruction.Value is long || ldcInstruction.Value is double ? 2 : 1; @@ -137,12 +127,11 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) case LookupSwitchInstruction lookupSwitchInstruction: newStackSize--; EnqueueInstruction(lookupSwitchInstruction.Default, newStackSize); - foreach (var jumpPoint in lookupSwitchInstruction.MatchLabels) + foreach (KeyValuePair jumpPoint in lookupSwitchInstruction.MatchLabels) EnqueueInstruction(jumpPoint.Value, newStackSize); continue; case MethodInstruction methodInstruction: - if (methodInstruction.Opcode != Opcode.INVOKESTATIC) - { + if (methodInstruction.Opcode != Opcode.INVOKESTATIC) { newStackSize--; CheckStackSizeAndThrow(newStackSize); } @@ -163,10 +152,8 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) break; case SimpleInstruction simpleInstruction: // ReSharper disable once SwitchStatementMissingSomeCases - switch (simpleInstruction.Opcode) - { - case Opcode.NOP: - break; + switch (simpleInstruction.Opcode) { + case Opcode.NOP: break; case Opcode.ACONST_NULL: case Opcode.ICONST_M1: case Opcode.ICONST_0: @@ -178,24 +165,24 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) case Opcode.FCONST_0: case Opcode.FCONST_1: case Opcode.FCONST_2: - newStackSize++; - break; + newStackSize++; + break; case Opcode.LCONST_0: case Opcode.LCONST_1: case Opcode.DCONST_0: case Opcode.DCONST_1: - newStackSize += 2; - break; + newStackSize += 2; + break; case Opcode.IALOAD: case Opcode.FALOAD: case Opcode.AALOAD: case Opcode.BALOAD: case Opcode.CALOAD: case Opcode.SALOAD: - newStackSize -= 2; - CheckStackSizeAndThrow(newStackSize); - newStackSize++; - break; + newStackSize -= 2; + CheckStackSizeAndThrow(newStackSize); + newStackSize++; + break; case Opcode.LALOAD: case Opcode.DALOAD: newStackSize -= 2; @@ -207,10 +194,10 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) case Opcode.I2D: case Opcode.F2L: case Opcode.F2D: - newStackSize--; - CheckStackSizeAndThrow(newStackSize); - newStackSize += 2; - break; + newStackSize--; + CheckStackSizeAndThrow(newStackSize); + newStackSize += 2; + break; case Opcode.IASTORE: case Opcode.FASTORE: case Opcode.AASTORE: @@ -220,51 +207,51 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) newStackSize -= 3; break; case Opcode.POP2: - newStackSize -= 2; - break; + newStackSize -= 2; + break; case Opcode.DASTORE: case Opcode.LASTORE: - newStackSize -= 4; - break; + newStackSize -= 4; + break; case Opcode.POP: case Opcode.MONITORENTER: case Opcode.MONITOREXIT: - newStackSize--; - break; + newStackSize--; + break; case Opcode.DUP_X1: - newStackSize -= 2; + newStackSize -= 2; CheckStackSizeAndThrow(newStackSize); - newStackSize += 3; - break; + newStackSize += 3; + break; case Opcode.DUP_X2: - newStackSize -= 3; + newStackSize -= 3; CheckStackSizeAndThrow(newStackSize); - newStackSize += 4; - break; + newStackSize += 4; + break; case Opcode.DUP2: - newStackSize -= 2; + newStackSize -= 2; CheckStackSizeAndThrow(newStackSize); - newStackSize += 4; - break; + newStackSize += 4; + break; case Opcode.DUP2_X1: - newStackSize -= 3; + newStackSize -= 3; CheckStackSizeAndThrow(newStackSize); - newStackSize += 5; - break; + newStackSize += 5; + break; case Opcode.DUP2_X2: - newStackSize -= 4; + newStackSize -= 4; CheckStackSizeAndThrow(newStackSize); - newStackSize += 6; - break; + newStackSize += 6; + break; case Opcode.SWAP: case Opcode.LNEG: case Opcode.DNEG: case Opcode.L2D: case Opcode.D2L: - newStackSize -= 2; - CheckStackSizeAndThrow(newStackSize); - newStackSize += 2; - break; + newStackSize -= 2; + CheckStackSizeAndThrow(newStackSize); + newStackSize += 2; + break; case Opcode.IADD: case Opcode.FADD: case Opcode.ISUB: @@ -283,10 +270,10 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) case Opcode.IUSHR: case Opcode.FCMPL: case Opcode.FCMPG: - newStackSize -= 2; - CheckStackSizeAndThrow(newStackSize); - newStackSize++; - break; + newStackSize -= 2; + CheckStackSizeAndThrow(newStackSize); + newStackSize++; + break; case Opcode.LADD: case Opcode.DADD: case Opcode.LSUB: @@ -300,10 +287,10 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) case Opcode.LAND: case Opcode.LOR: case Opcode.LXOR: - newStackSize -= 4; - CheckStackSizeAndThrow(newStackSize); - newStackSize += 2; - break; + newStackSize -= 4; + CheckStackSizeAndThrow(newStackSize); + newStackSize += 2; + break; case Opcode.INEG: case Opcode.FNEG: case Opcode.I2F: @@ -312,61 +299,59 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) case Opcode.I2C: case Opcode.I2S: case Opcode.ARRAYLENGTH: - newStackSize--; - CheckStackSizeAndThrow(newStackSize); - newStackSize++; - break; + newStackSize--; + CheckStackSizeAndThrow(newStackSize); + newStackSize++; + break; case Opcode.LSHL: case Opcode.LSHR: case Opcode.LUSHR: - newStackSize -= 3; - CheckStackSizeAndThrow(newStackSize); - newStackSize += 2; - break; + newStackSize -= 3; + CheckStackSizeAndThrow(newStackSize); + newStackSize += 2; + break; case Opcode.L2I: case Opcode.L2F: case Opcode.D2I: case Opcode.D2F: - newStackSize -= 2; - CheckStackSizeAndThrow(newStackSize); - newStackSize++; - break; + newStackSize -= 2; + CheckStackSizeAndThrow(newStackSize); + newStackSize++; + break; case Opcode.LCMP: case Opcode.DCMPL: case Opcode.DCMPG: - newStackSize -= 4; - CheckStackSizeAndThrow(newStackSize); - newStackSize++; - break; + newStackSize -= 4; + CheckStackSizeAndThrow(newStackSize); + newStackSize++; + break; case Opcode.ARETURN: case Opcode.IRETURN: case Opcode.FRETURN: case Opcode.ATHROW: - newStackSize--; - CheckStackSizeAndThrow(newStackSize); - continue; + newStackSize--; + CheckStackSizeAndThrow(newStackSize); + continue; case Opcode.LRETURN: case Opcode.DRETURN: - newStackSize -= 2; - CheckStackSizeAndThrow(newStackSize); - continue; - case Opcode.RETURN: - continue; - default: - throw new ArgumentOutOfRangeException(nameof(simpleInstruction.Opcode)); + newStackSize -= 2; + CheckStackSizeAndThrow(newStackSize); + continue; + case Opcode.RETURN: continue; + default: throw new ArgumentOutOfRangeException(nameof(simpleInstruction.Opcode)); } + break; case TableSwitchInstruction tableSwitchInstruction: newStackSize--; CheckStackSizeAndThrow(newStackSize); EnqueueInstruction(tableSwitchInstruction.Default, newStackSize); - foreach (var jumpPoint in tableSwitchInstruction.Labels) + foreach (Label jumpPoint in tableSwitchInstruction.Labels) EnqueueInstruction(jumpPoint, newStackSize); continue; case TypeInstruction typeInstruction: // ReSharper disable once SwitchStatementMissingSomeCases - switch (typeInstruction.Opcode) - { + switch (typeInstruction.Opcode) { case Opcode.NEW: newStackSize++; break; @@ -377,14 +362,13 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) CheckStackSizeAndThrow(newStackSize); newStackSize++; break; - default: - throw new ArgumentOutOfRangeException(nameof(typeInstruction.Opcode)); + default: throw new ArgumentOutOfRangeException(nameof(typeInstruction.Opcode)); } + break; case VariableInstruction variableInstruction: // ReSharper disable once SwitchStatementMissingSomeCases - switch (variableInstruction.Opcode) - { + switch (variableInstruction.Opcode) { case Opcode.ALOAD: case Opcode.ILOAD: case Opcode.FLOAD: @@ -403,21 +387,19 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) case Opcode.DSTORE: newStackSize -= 2; break; - case Opcode.RET: - break; - default: - throw new ArgumentOutOfRangeException(nameof(variableInstruction.Opcode)); + case Opcode.RET: break; + default: throw new ArgumentOutOfRangeException(nameof(variableInstruction.Opcode)); } + break; case StackMapFrame _: case IncrementInstruction _: case LineNumber _: case Label _: break; - default: - throw new ArgumentOutOfRangeException(nameof(currentInstruction)); + default: throw new ArgumentOutOfRangeException(nameof(currentInstruction)); } - + EnqueueInstruction(currentInstruction.Next, newStackSize); } @@ -428,9 +410,8 @@ void EnqueueInstruction(Instruction instruction, int newStackSize) /// Computes stack frames /// /// Method to compute for - public static void ComputeStackMapFrames(MethodNode methodNode) - { + public static void ComputeStackMapFrames(MethodNode methodNode) { throw new NotImplementedException(); } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/Annotation/AnnotationNode.cs b/JavaAsm/CustomAttributes/Annotation/AnnotationNode.cs index 108f7f8..0d643dc 100644 --- a/JavaAsm/CustomAttributes/Annotation/AnnotationNode.cs +++ b/JavaAsm/CustomAttributes/Annotation/AnnotationNode.cs @@ -22,14 +22,14 @@ public class ElementValuePair internal static AnnotationNode Parse(Stream stream, ClassReaderState readerState) { - var annotation = new AnnotationNode + AnnotationNode annotation = new AnnotationNode { Type = TypeDescriptor.Parse(readerState.ConstantPool .GetEntry(Binary.BigEndian.ReadUInt16(stream)).String) }; - var elementValuePairsCount = Binary.BigEndian.ReadUInt16(stream); + ushort elementValuePairsCount = Binary.BigEndian.ReadUInt16(stream); annotation.ElementValuePairs.Capacity = elementValuePairsCount; - for (var i = 0; i < elementValuePairsCount; i++) + for (int i = 0; i < elementValuePairsCount; i++) annotation.ElementValuePairs.Add(new ElementValuePair { ElementName = readerState.ConstantPool @@ -41,12 +41,12 @@ internal static AnnotationNode Parse(Stream stream, ClassReaderState readerState internal void Write(Stream stream, ClassWriterState writerState) { - Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new Utf8Entry(Type.ToString()))); - if (ElementValuePairs.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(ElementValuePairs.Count), - $"Too many ElementValues: {ElementValuePairs.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(stream, (ushort) ElementValuePairs.Count); - foreach (var elementValuePair in ElementValuePairs) + Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new Utf8Entry(this.Type.ToString()))); + if (this.ElementValuePairs.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.ElementValuePairs.Count), + $"Too many ElementValues: {this.ElementValuePairs.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(stream, (ushort) this.ElementValuePairs.Count); + foreach (ElementValuePair elementValuePair in this.ElementValuePairs) { Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new Utf8Entry(elementValuePair.ElementName))); diff --git a/JavaAsm/CustomAttributes/Annotation/ElementValue.cs b/JavaAsm/CustomAttributes/Annotation/ElementValue.cs index 61e2a8f..727ed76 100644 --- a/JavaAsm/CustomAttributes/Annotation/ElementValue.cs +++ b/JavaAsm/CustomAttributes/Annotation/ElementValue.cs @@ -48,7 +48,7 @@ public class EnumConstValueType internal static ElementValue Parse(Stream stream, ClassReaderState readerState) { - var elementValue = new ElementValue + ElementValue elementValue = new ElementValue { Tag = (ElementValueTag) stream.ReadByteFully() }; @@ -91,9 +91,9 @@ internal static ElementValue Parse(Stream stream, ClassReaderState readerState) elementValue.AnnotationNode = AnnotationNode.Parse(stream, readerState); break; case ElementValueTag.Array: - var arraySize = Binary.BigEndian.ReadUInt16(stream); + ushort arraySize = Binary.BigEndian.ReadUInt16(stream); elementValue.ArrayValue = new List(arraySize); - for (var i = 0; i < arraySize; i++) + for (int i = 0; i < arraySize; i++) elementValue.ArrayValue.Add(Parse(stream, readerState)); break; default: @@ -105,50 +105,50 @@ internal static ElementValue Parse(Stream stream, ClassReaderState readerState) internal void Write(Stream stream, ClassWriterState writerState) { - stream.WriteByte((byte) Tag); - switch (Tag) + stream.WriteByte((byte) this.Tag); + switch (this.Tag) { case ElementValueTag.Byte: case ElementValueTag.Character: case ElementValueTag.Integer: case ElementValueTag.Short: case ElementValueTag.Boolean: - Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new IntegerEntry((int) ConstValue))); + Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new IntegerEntry((int) this.ConstValue))); break; case ElementValueTag.Double: - Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new DoubleEntry((double) ConstValue))); + Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new DoubleEntry((double) this.ConstValue))); break; case ElementValueTag.Float: - Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new FloatEntry((float) ConstValue))); + Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new FloatEntry((float) this.ConstValue))); break; case ElementValueTag.Long: - Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new LongEntry((long) ConstValue))); + Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new LongEntry((long) this.ConstValue))); break; case ElementValueTag.String: - Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new Utf8Entry((string) ConstValue))); + Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new Utf8Entry((string) this.ConstValue))); break; case ElementValueTag.Enum: Binary.BigEndian.Write(stream, - writerState.ConstantPool.Find(new Utf8Entry(EnumConstValue.TypeName.ToString()))); + writerState.ConstantPool.Find(new Utf8Entry(this.EnumConstValue.TypeName.ToString()))); Binary.BigEndian.Write(stream, - writerState.ConstantPool.Find(new Utf8Entry(EnumConstValue.ConstName))); + writerState.ConstantPool.Find(new Utf8Entry(this.EnumConstValue.ConstName))); break; case ElementValueTag.Class: Binary.BigEndian.Write(stream, - writerState.ConstantPool.Find(new Utf8Entry(Class.ToString()))); + writerState.ConstantPool.Find(new Utf8Entry(this.Class.ToString()))); break; case ElementValueTag.Annotation: - AnnotationNode.Write(stream, writerState); + this.AnnotationNode.Write(stream, writerState); break; case ElementValueTag.Array: - if (ArrayValue.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(ArrayValue.Count), $"Array size is too big: {ArrayValue.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(stream, (ushort) ArrayValue.Count); - foreach (var element in ArrayValue) + if (this.ArrayValue.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.ArrayValue.Count), $"Array size is too big: {this.ArrayValue.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(stream, (ushort) this.ArrayValue.Count); + foreach (ElementValue element in this.ArrayValue) element.Write(stream, writerState); break; default: - throw new ArgumentOutOfRangeException(nameof(Tag)); + throw new ArgumentOutOfRangeException(nameof(this.Tag)); } } } diff --git a/JavaAsm/CustomAttributes/AnnotationDefaultAttribute.cs b/JavaAsm/CustomAttributes/AnnotationDefaultAttribute.cs index 3472c27..4108191 100644 --- a/JavaAsm/CustomAttributes/AnnotationDefaultAttribute.cs +++ b/JavaAsm/CustomAttributes/AnnotationDefaultAttribute.cs @@ -10,9 +10,9 @@ public class AnnotationDefaultAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - Value.Write(attributeDataStream, writerState); + this.Value.Write(attributeDataStream, writerState); return attributeDataStream.ToArray(); } diff --git a/JavaAsm/CustomAttributes/BootstrapMethodsAttribute.cs b/JavaAsm/CustomAttributes/BootstrapMethodsAttribute.cs index 60f8023..5cff78c 100644 --- a/JavaAsm/CustomAttributes/BootstrapMethodsAttribute.cs +++ b/JavaAsm/CustomAttributes/BootstrapMethodsAttribute.cs @@ -16,18 +16,18 @@ public class BootstrapMethod public BootstrapMethod(Handle bootstrapMethodReference) { - BootstrapMethodReference = bootstrapMethodReference; + this.BootstrapMethodReference = bootstrapMethodReference; } public BootstrapMethod(Handle bootstrapMethodReference, List arguments) { - BootstrapMethodReference = bootstrapMethodReference; - Arguments = arguments; + this.BootstrapMethodReference = bootstrapMethodReference; + this.Arguments = arguments; } public bool Equals(BootstrapMethod other) { - return BootstrapMethodReference.Equals(other.BootstrapMethodReference) && Arguments.Equals(other.Arguments); + return this.BootstrapMethodReference.Equals(other.BootstrapMethodReference) && this.Arguments.Equals(other.Arguments); } public override bool Equals(object obj) @@ -41,48 +41,59 @@ public override int GetHashCode() { unchecked { - return (BootstrapMethodReference.GetHashCode() * 397) ^ Arguments.GetHashCode(); + return (this.BootstrapMethodReference.GetHashCode() * 397) ^ this.Arguments.GetHashCode(); } } } - internal class BootstrapMethodsAttribute : CustomAttribute - { + internal class BootstrapMethodsAttribute : CustomAttribute { public List BootstrapMethods { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { - using var attributeDataStream = new MemoryStream(); + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { + using (MemoryStream attributeDataStream = new MemoryStream()) { + if (this.BootstrapMethods.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.BootstrapMethods.Count), $"Number of bootstrap methods is too big: {this.BootstrapMethods.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.BootstrapMethods.Count); + foreach (BootstrapMethod method in this.BootstrapMethods) { + Binary.BigEndian.Write(attributeDataStream, + writerState.ConstantPool.Find(method.BootstrapMethodReference.ToConstantPool())); + if (method.Arguments.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(method.Arguments.Count), + $"Number of arguments is too big: {method.Arguments.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) method.Arguments.Count); + foreach (object argument in method.Arguments) { + Entry val; + if (argument is int) { + val = new IntegerEntry((int) argument); + } + else if (argument is float) { + val = new FloatEntry((float) argument); + } + else if (argument is string) { + val = new StringEntry(new Utf8Entry((string) argument)); + } + else if (argument is long) { + val = new LongEntry((long) argument); + } + else if (argument is double) { + val = new DoubleEntry((double) argument); + } + else if (argument is Handle) { + val = ((Handle) argument).ToConstantPool(); + } + else if (argument is MethodDescriptor) { + val = new MethodTypeEntry(new Utf8Entry(((MethodDescriptor) argument).ToString())); } + else { + throw new ArgumentOutOfRangeException(nameof(argument), $"Can't encode value of type {argument.GetType()}"); + } - if (BootstrapMethods.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(BootstrapMethods.Count), $"Number of bootstrap methods is too big: {BootstrapMethods.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort) BootstrapMethods.Count); - foreach (var method in BootstrapMethods) - { - Binary.BigEndian.Write(attributeDataStream, - writerState.ConstantPool.Find(method.BootstrapMethodReference.ToConstantPool())); - if (method.Arguments.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(method.Arguments.Count), - $"Number of arguments is too big: {method.Arguments.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort) method.Arguments.Count); - foreach (var argument in method.Arguments) - { - Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(argument switch - { - int integerValue => (Entry) new IntegerEntry(integerValue), - float floatValue => new FloatEntry(floatValue), - string stringValue => new StringEntry(new Utf8Entry(stringValue)), - long longValue => new LongEntry(longValue), - double doubleValue => new DoubleEntry(doubleValue), - Handle handle => handle.ToConstantPool(), - MethodDescriptor methodDescriptor => new MethodTypeEntry(new Utf8Entry(methodDescriptor.ToString())), - _ => throw new ArgumentOutOfRangeException(nameof(argument), $"Can't encode value of type {argument.GetType()}") - })); + Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(val)); + } } - } - return attributeDataStream.ToArray(); + return attributeDataStream.ToArray(); + } } } @@ -90,35 +101,51 @@ internal class BootstrapMethodsAttributeFactory : ICustomAttributeFactory( Binary.BigEndian.ReadUInt16(attributeDataStream)))); - var numberOfArguments = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort numberOfArguments = Binary.BigEndian.ReadUInt16(attributeDataStream); bootstrapMethod.Arguments.Capacity = numberOfArguments; - for (var j = 0; j < numberOfArguments; j++) - { - var argumentValueEntry = + for (int j = 0; j < numberOfArguments; j++) { + Entry argumentValueEntry = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)); - bootstrapMethod.Arguments.Add(argumentValueEntry switch - { - StringEntry stringEntry => stringEntry.Value.String, - ClassEntry classEntry => new ClassName(classEntry.Name.String), - IntegerEntry integerEntry => (object) integerEntry.Value, - LongEntry longEntry => longEntry.Value, - FloatEntry floatEntry => floatEntry.Value, - DoubleEntry doubleEntry => doubleEntry.Value, - MethodHandleEntry methodHandleEntry => Handle.FromConstantPool(methodHandleEntry), - MethodTypeEntry methodTypeEntry => MethodDescriptor.Parse(methodTypeEntry.Descriptor.String), - _ => throw new ArgumentOutOfRangeException(nameof(argumentValueEntry), - $"Entry of type {argumentValueEntry.Tag} is not supported for argument of bootstrap method") - }); + object item; + if (argumentValueEntry is StringEntry se) { + item = se.Value.String; + } + else if (argumentValueEntry is ClassEntry ce) { + item = new ClassName(ce.Name.String); + } + else if (argumentValueEntry is IntegerEntry ie) { + item = ie.Value; + } + else if (argumentValueEntry is LongEntry le) { + item = le.Value; + } + else if (argumentValueEntry is FloatEntry fe) { + item = fe.Value; + } + else if (argumentValueEntry is DoubleEntry de) { + item = de.Value; + } + else if (argumentValueEntry is MethodHandleEntry mhe) { + item = Handle.FromConstantPool(mhe); + } + else if (argumentValueEntry is MethodTypeEntry mte) { + item = MethodDescriptor.Parse(mte.Descriptor.String); + } + else { + throw new ArgumentOutOfRangeException(nameof(argumentValueEntry), $"Entry of type {argumentValueEntry.Tag} is not supported for argument of bootstrap method"); + } + + bootstrapMethod.Arguments.Add(item); } attribute.BootstrapMethods.Add(bootstrapMethod); } diff --git a/JavaAsm/CustomAttributes/CodeAttribute.cs b/JavaAsm/CustomAttributes/CodeAttribute.cs index e1adc01..4c50302 100644 --- a/JavaAsm/CustomAttributes/CodeAttribute.cs +++ b/JavaAsm/CustomAttributes/CodeAttribute.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using BinaryEncoding; +using JavaAsm.Helpers; using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; @@ -32,32 +33,32 @@ public class ExceptionTableEntry internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - Binary.BigEndian.Write(attributeDataStream, MaxStack); - Binary.BigEndian.Write(attributeDataStream, MaxLocals); + Binary.BigEndian.Write(attributeDataStream, this.MaxStack); + Binary.BigEndian.Write(attributeDataStream, this.MaxLocals); - if (Code.LongLength > uint.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Code.LongLength), $"Code length too big: {Code.LongLength} > {uint.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (uint) Code.LongLength); - attributeDataStream.Write(Code); + if (this.Code.LongLength > uint.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Code.LongLength), $"Code length too big: {this.Code.LongLength} > {uint.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (uint) this.Code.LongLength); + attributeDataStream.Write(this.Code); - if (ExceptionTable.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(ExceptionTable.Count), $"Exception table too big: {ExceptionTable.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort) ExceptionTable.Count); - foreach (var exceptionTableEntry in ExceptionTable) + if (this.ExceptionTable.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.ExceptionTable.Count), $"Exception table too big: {this.ExceptionTable.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.ExceptionTable.Count); + foreach (ExceptionTableEntry exceptionTableEntry in this.ExceptionTable) { Binary.BigEndian.Write(attributeDataStream, exceptionTableEntry.StartPc); Binary.BigEndian.Write(attributeDataStream, exceptionTableEntry.EndPc); Binary.BigEndian.Write(attributeDataStream, exceptionTableEntry.HandlerPc); - Binary.BigEndian.Write(attributeDataStream, (ushort) (exceptionTableEntry.CatchType == null ? 0 : + Binary.BigEndian.Write(attributeDataStream, (ushort) (exceptionTableEntry.CatchType == null ? 0 : writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(exceptionTableEntry.CatchType.Name))))); } - if (Attributes.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Attributes.Count), $"Too many attributes: {Attributes.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort) Attributes.Count); - foreach (var attriute in Attributes) + if (this.Attributes.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Attributes.Count), $"Too many attributes: {this.Attributes.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.Attributes.Count); + foreach (AttributeNode attriute in this.Attributes) ClassFile.WriteAttribute(attributeDataStream, attriute, writerState, AttributeScope.Code); return attributeDataStream.ToArray(); @@ -68,28 +69,28 @@ internal class CodeAttributeFactory : ICustomAttributeFactory { public CodeAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { - var maxStack = Binary.BigEndian.ReadUInt16(attributeDataStream); - var maxLocals = Binary.BigEndian.ReadUInt16(attributeDataStream); - var code = new byte[Binary.BigEndian.ReadUInt32(attributeDataStream)]; + ushort maxStack = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort maxLocals = Binary.BigEndian.ReadUInt16(attributeDataStream); + byte[] code = new byte[Binary.BigEndian.ReadUInt32(attributeDataStream)]; attributeDataStream.Read(code); - var attribute = new CodeAttribute + CodeAttribute attribute = new CodeAttribute { MaxStack = maxStack, MaxLocals = maxLocals, Code = code }; - var exceptionTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort exceptionTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.ExceptionTable.Capacity = exceptionTableSize; - for (var i = 0; i < exceptionTableSize; i++) + for (int i = 0; i < exceptionTableSize; i++) { - var exceptionTableEntry = new CodeAttribute.ExceptionTableEntry + CodeAttribute.ExceptionTableEntry exceptionTableEntry = new CodeAttribute.ExceptionTableEntry { StartPc = Binary.BigEndian.ReadUInt16(attributeDataStream), EndPc = Binary.BigEndian.ReadUInt16(attributeDataStream), HandlerPc = Binary.BigEndian.ReadUInt16(attributeDataStream) }; - var catchTypeIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort catchTypeIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); if (catchTypeIndex != 0) { @@ -101,9 +102,9 @@ public CodeAttribute Parse(Stream attributeDataStream, uint attributeDataLength, attribute.ExceptionTable.Add(exceptionTableEntry); } - var attributesCount = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort attributesCount = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.Attributes.Capacity = attributesCount; - for (var i = 0; i < attributesCount; i++) + for (int i = 0; i < attributesCount; i++) attribute.Attributes.Add(ClassFile.ParseAttribute(attributeDataStream, readerState, AttributeScope.Code)); return attribute; diff --git a/JavaAsm/CustomAttributes/ConstantValueAttribute.cs b/JavaAsm/CustomAttributes/ConstantValueAttribute.cs index a2048ed..efe041e 100644 --- a/JavaAsm/CustomAttributes/ConstantValueAttribute.cs +++ b/JavaAsm/CustomAttributes/ConstantValueAttribute.cs @@ -10,18 +10,19 @@ public class ConstantValueAttribute : CustomAttribute { public object Value { get; set; } - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { - var result = new byte[2]; - Binary.BigEndian.Set(Value switch - { - long longValue => writerState.ConstantPool.Find(new LongEntry(longValue)), - float floatValue => writerState.ConstantPool.Find(new FloatEntry(floatValue)), - double doubleValue => writerState.ConstantPool.Find(new DoubleEntry(doubleValue)), - int integerValue => writerState.ConstantPool.Find(new IntegerEntry(integerValue)), - string stringValue => writerState.ConstantPool.Find(new StringEntry(new Utf8Entry(stringValue))), - _ => throw new ArgumentOutOfRangeException(nameof(Value), $"Can't encode value of type {Value.GetType()}") - }, result); + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { + ushort value; + switch (this.Value) { + case long longValue: value = writerState.ConstantPool.Find(new LongEntry(longValue)); break; + case float floatValue: value = writerState.ConstantPool.Find(new FloatEntry(floatValue)); break; + case double doubleValue: value = writerState.ConstantPool.Find(new DoubleEntry(doubleValue)); break; + case int integerValue: value = writerState.ConstantPool.Find(new IntegerEntry(integerValue)); break; + case string stringValue: value = writerState.ConstantPool.Find(new StringEntry(new Utf8Entry(stringValue))); break; + default: throw new ArgumentOutOfRangeException(nameof(this.Value), $"Can't encode value of type {this.Value.GetType()}"); + } + + byte[] result = new byte[2]; + Binary.BigEndian.Set(value, result); return result; } } @@ -30,19 +31,18 @@ internal class ConstantValueAttributeFactory : ICustomAttributeFactory(Binary.BigEndian.ReadUInt16(attributeDataStream)); - return new ConstantValueAttribute { - Value = entry switch - { - LongEntry longEntry => (longEntry.Value as object), - FloatEntry floatEntry => floatEntry.Value, - DoubleEntry doubleEntry => doubleEntry.Value, - IntegerEntry integerEntry => integerEntry.Value, - StringEntry stringEntry => stringEntry.Value.String, - _ => throw new ArgumentOutOfRangeException(nameof(entry), - $"Can't use constant pool entry of type {entry.GetType()} as constant value") - } - }; + Entry entry = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)); + object value; + switch (entry) { + case LongEntry longEntry: value = longEntry.Value; break; + case FloatEntry floatEntry: value = floatEntry.Value; break; + case DoubleEntry doubleEntry: value = doubleEntry.Value; break; + case IntegerEntry integerEntry: value = integerEntry.Value; break; + case StringEntry stringEntry: value = stringEntry.Value.String; break; + default: throw new ArgumentOutOfRangeException(nameof(entry), $"Can't use constant pool entry of type {entry.GetType()} as constant value"); + } + + return new ConstantValueAttribute {Value = value}; } } } diff --git a/JavaAsm/CustomAttributes/EnclosingMethodAttribute.cs b/JavaAsm/CustomAttributes/EnclosingMethodAttribute.cs index 9b40f50..12cc38d 100644 --- a/JavaAsm/CustomAttributes/EnclosingMethodAttribute.cs +++ b/JavaAsm/CustomAttributes/EnclosingMethodAttribute.cs @@ -14,20 +14,20 @@ public class EnclosingMethodAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); Binary.BigEndian.Write(attributeDataStream, - writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(Class.Name)))); + writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(this.Class.Name)))); - if (MethodName == null && MethodDescriptor == null) + if (this.MethodName == null && this.MethodDescriptor == null) { Binary.BigEndian.Write(attributeDataStream, (ushort) 0); - } + } else { Binary.BigEndian.Write(attributeDataStream, - writerState.ConstantPool.Find(new NameAndTypeEntry(new Utf8Entry(MethodName), - new Utf8Entry(MethodDescriptor.ToString())))); + writerState.ConstantPool.Find(new NameAndTypeEntry(new Utf8Entry(this.MethodName), + new Utf8Entry(this.MethodDescriptor.ToString())))); } return attributeDataStream.ToArray(); @@ -38,18 +38,18 @@ internal class EnclosingMethodAttributeFactory : ICustomAttributeFactory(Binary.BigEndian.ReadUInt16(attributeDataStream)).Name.String) }; - var nameAndTypeEntryIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort nameAndTypeEntryIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); - if (nameAndTypeEntryIndex == 0) + if (nameAndTypeEntryIndex == 0) return attribute; - var nameAndTypeEntry = readerState.ConstantPool.GetEntry(nameAndTypeEntryIndex); + NameAndTypeEntry nameAndTypeEntry = readerState.ConstantPool.GetEntry(nameAndTypeEntryIndex); attribute.MethodName = nameAndTypeEntry.Name.String; attribute.MethodDescriptor = MethodDescriptor.Parse(nameAndTypeEntry.Descriptor.String); diff --git a/JavaAsm/CustomAttributes/ExceptionsAttribute.cs b/JavaAsm/CustomAttributes/ExceptionsAttribute.cs index ad0505d..f07371b 100644 --- a/JavaAsm/CustomAttributes/ExceptionsAttribute.cs +++ b/JavaAsm/CustomAttributes/ExceptionsAttribute.cs @@ -13,13 +13,13 @@ public class ExceptionsAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - if (ExceptionTable.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(ExceptionTable.Count), - $"Exception table size too big: {ExceptionTable.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort) ExceptionTable.Count); - foreach (var exceptionClassName in ExceptionTable) + if (this.ExceptionTable.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.ExceptionTable.Count), + $"Exception table size too big: {this.ExceptionTable.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.ExceptionTable.Count); + foreach (ClassName exceptionClassName in this.ExceptionTable) Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(exceptionClassName.Name)))); @@ -31,11 +31,11 @@ internal class ExceptionsAttributeFactory : ICustomAttributeFactory(Binary.BigEndian.ReadUInt16(attributeDataStream)).Name.String)); diff --git a/JavaAsm/CustomAttributes/InnerClassesAttribute.cs b/JavaAsm/CustomAttributes/InnerClassesAttribute.cs index 4514c3f..ca526d7 100644 --- a/JavaAsm/CustomAttributes/InnerClassesAttribute.cs +++ b/JavaAsm/CustomAttributes/InnerClassesAttribute.cs @@ -13,12 +13,12 @@ public class InnerClassesAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - if (Classes.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Classes.Count), $"Too many inner classes: {Classes.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort)Classes.Count); - foreach (var innerClass in Classes) + if (this.Classes.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Classes.Count), $"Too many inner classes: {this.Classes.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.Classes.Count); + foreach (InnerClass innerClass in this.Classes) { Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(innerClass.InnerClassName.Name)))); @@ -45,7 +45,7 @@ public class InnerClass public override string ToString() { - return $"{AccessModifiersExtensions.ToString(Access)} {InnerClassName?.ToString() ?? "null"} {OuterClassName?.ToString() ?? "null"} {InnerName?.ToString() ?? "null"}"; + return $"{AccessModifiersExtensions.ToString(this.Access)} {this.InnerClassName?.ToString() ?? "null"} {this.OuterClassName?.ToString() ?? "null"} {this.InnerName?.ToString() ?? "null"}"; } } @@ -53,22 +53,22 @@ internal class InnerClassesAttributeFactory : ICustomAttributeFactory(Binary.BigEndian.ReadUInt16(attributeDataStream)).Name.String) }; - var outerClassIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort outerClassIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); if (outerClassIndex != 0) innerClass.OuterClassName = new ClassName(readerState.ConstantPool .GetEntry(outerClassIndex).Name.String); - var innerNameIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort innerNameIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); if (innerNameIndex != 0) innerClass.InnerName = readerState.ConstantPool .GetEntry(innerNameIndex).String; diff --git a/JavaAsm/CustomAttributes/LineNumberTableAttribute.cs b/JavaAsm/CustomAttributes/LineNumberTableAttribute.cs index a40d814..5f9d772 100644 --- a/JavaAsm/CustomAttributes/LineNumberTableAttribute.cs +++ b/JavaAsm/CustomAttributes/LineNumberTableAttribute.cs @@ -19,12 +19,12 @@ public class LineNumberTableEntry internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - if (LineNumberTable.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(LineNumberTable.Count), $"Line number table too big: {LineNumberTable.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort)LineNumberTable.Count); - foreach (var exceptionTableEntry in LineNumberTable) + if (this.LineNumberTable.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.LineNumberTable.Count), $"Line number table too big: {this.LineNumberTable.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.LineNumberTable.Count); + foreach (LineNumberTableEntry exceptionTableEntry in this.LineNumberTable) { Binary.BigEndian.Write(attributeDataStream, exceptionTableEntry.StartPc); Binary.BigEndian.Write(attributeDataStream, exceptionTableEntry.LineNumber); @@ -38,11 +38,11 @@ internal class LineNumberTableAttributeFactory : ICustomAttributeFactory ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(LocalVariableTable.Count), $"Local variable table is too big: {LocalVariableTable.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort) LocalVariableTable.Count); - foreach (var localVariableTableEntry in LocalVariableTable) + if (this.LocalVariableTable.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.LocalVariableTable.Count), $"Local variable table is too big: {this.LocalVariableTable.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.LocalVariableTable.Count); + foreach (LocalVariableTableEntry localVariableTableEntry in this.LocalVariableTable) { Binary.BigEndian.Write(attributeDataStream, localVariableTableEntry.StartPc); Binary.BigEndian.Write(attributeDataStream, localVariableTableEntry.Length); @@ -50,11 +50,11 @@ internal class LocalVariableTableAttributeFactory : ICustomAttributeFactory ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(LocalVariableTypeTable.Count), $"Local variable type table is too big: {LocalVariableTypeTable.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort)LocalVariableTypeTable.Count); - foreach (var localVariableTypeTableEntry in LocalVariableTypeTable) + if (this.LocalVariableTypeTable.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.LocalVariableTypeTable.Count), $"Local variable type table is too big: {this.LocalVariableTypeTable.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.LocalVariableTypeTable.Count); + foreach (LocalVariableTypeTableEntry localVariableTypeTableEntry in this.LocalVariableTypeTable) { Binary.BigEndian.Write(attributeDataStream, localVariableTypeTableEntry.StartPc); Binary.BigEndian.Write(attributeDataStream, localVariableTypeTableEntry.Length); @@ -50,11 +50,11 @@ internal class LocalVariableTypeTableAttributeFactory : ICustomAttributeFactory< { public LocalVariableTypeTableAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { - var attribute = new LocalVariableTypeTableAttribute(); + LocalVariableTypeTableAttribute attribute = new LocalVariableTypeTableAttribute(); - var localVariableTypeTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort localVariableTypeTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.LocalVariableTypeTable.Capacity = localVariableTypeTableSize; - for (var i = 0; i < localVariableTypeTableSize; i++) + for (int i = 0; i < localVariableTypeTableSize; i++) attribute.LocalVariableTypeTable.Add(new LocalVariableTypeTableAttribute.LocalVariableTypeTableEntry { StartPc = Binary.BigEndian.ReadUInt16(attributeDataStream), diff --git a/JavaAsm/CustomAttributes/MethodParametersAttribute.cs b/JavaAsm/CustomAttributes/MethodParametersAttribute.cs index d22dcb3..29c653d 100644 --- a/JavaAsm/CustomAttributes/MethodParametersAttribute.cs +++ b/JavaAsm/CustomAttributes/MethodParametersAttribute.cs @@ -21,12 +21,12 @@ public class Parameter internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - if (Parameters.Count > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Parameters.Count), $"Too many parameters: {Parameters.Count} > {byte.MaxValue}"); - attributeDataStream.WriteByte((byte) Parameters.Count); - foreach (var parameter in Parameters) + if (this.Parameters.Count > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Parameters.Count), $"Too many parameters: {this.Parameters.Count} > {byte.MaxValue}"); + attributeDataStream.WriteByte((byte) this.Parameters.Count); + foreach (Parameter parameter in this.Parameters) { Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new Utf8Entry(parameter.Name))); @@ -41,11 +41,11 @@ internal class MethodParametersAttributeFactory : ICustomAttributeFactory(Binary.BigEndian.ReadUInt16(attributeDataStream)).String, diff --git a/JavaAsm/CustomAttributes/RuntimeInvisibleAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeInvisibleAnnotationsAttribute.cs index 3ff2067..b788e78 100644 --- a/JavaAsm/CustomAttributes/RuntimeInvisibleAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeInvisibleAnnotationsAttribute.cs @@ -13,12 +13,12 @@ public class RuntimeInvisibleAnnotationsAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - if (Annotations.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Annotations.Count), $"Number of annotations is too big: {Annotations.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort)Annotations.Count); - foreach (var annotation in Annotations) + if (this.Annotations.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Annotations.Count), $"Number of annotations is too big: {this.Annotations.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.Annotations.Count); + foreach (AnnotationNode annotation in this.Annotations) annotation.Write(attributeDataStream, writerState); return attributeDataStream.ToArray(); @@ -29,11 +29,11 @@ internal class RuntimeInvisibleAnnotationsAttributeFactory : ICustomAttributeFac { public RuntimeInvisibleAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { - var attribute = new RuntimeInvisibleAnnotationsAttribute(); + RuntimeInvisibleAnnotationsAttribute attribute = new RuntimeInvisibleAnnotationsAttribute(); - var annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.Annotations.Capacity = annotationsCount; - for (var i = 0; i < annotationsCount; i++) + for (int i = 0; i < annotationsCount; i++) attribute.Annotations.Add(AnnotationNode.Parse(attributeDataStream, readerState)); return attribute; diff --git a/JavaAsm/CustomAttributes/RuntimeInvisibleParameterAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeInvisibleParameterAnnotationsAttribute.cs index fcbf15b..bf8750f 100644 --- a/JavaAsm/CustomAttributes/RuntimeInvisibleParameterAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeInvisibleParameterAnnotationsAttribute.cs @@ -20,18 +20,18 @@ public class RuntimeInvisibleParameterAnnotationsAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - if (Parameters.Count > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Parameters.Count), $"Number of parameters is too big: {Parameters.Count} > {byte.MaxValue}"); - attributeDataStream.WriteByte((byte)Parameters.Count); - foreach (var parameter in Parameters) + if (this.Parameters.Count > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Parameters.Count), $"Number of parameters is too big: {this.Parameters.Count} > {byte.MaxValue}"); + attributeDataStream.WriteByte((byte) this.Parameters.Count); + foreach (ParameterAnnotations parameter in this.Parameters) { if (parameter.Annotations.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(parameter.Annotations.Count), $"Number of annotations is too big: {parameter.Annotations.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(attributeDataStream, (ushort)parameter.Annotations.Count); - foreach (var annotation in parameter.Annotations) + foreach (AnnotationNode annotation in parameter.Annotations) annotation.Write(attributeDataStream, writerState); } @@ -43,16 +43,16 @@ internal class RuntimeInvisibleParameterAnnotationsAttributeFactory : ICustomAtt { public RuntimeInvisibleParameterAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { - var attribute = new RuntimeInvisibleParameterAnnotationsAttribute(); + RuntimeInvisibleParameterAnnotationsAttribute attribute = new RuntimeInvisibleParameterAnnotationsAttribute(); - var parametersCount = attributeDataStream.ReadByteFully(); + byte parametersCount = attributeDataStream.ReadByteFully(); attribute.Parameters.Capacity = parametersCount; - for (var i = 0; i < parametersCount; i++) + for (int i = 0; i < parametersCount; i++) { - var parameter = new ParameterAnnotations(); - var annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); + ParameterAnnotations parameter = new ParameterAnnotations(); + ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); parameter.Annotations.Capacity = annotationsCount; - for (var j = 0; j < annotationsCount; j++) + for (int j = 0; j < annotationsCount; j++) parameter.Annotations.Add(AnnotationNode.Parse(attributeDataStream, readerState)); attribute.Parameters.Add(parameter); } diff --git a/JavaAsm/CustomAttributes/RuntimeInvisibleTypeAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeInvisibleTypeAnnotationsAttribute.cs index eea52b5..b66a820 100644 --- a/JavaAsm/CustomAttributes/RuntimeInvisibleTypeAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeInvisibleTypeAnnotationsAttribute.cs @@ -13,12 +13,12 @@ public class RuntimeInvisibleTypeAnnotationsAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - if (Annotations.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Annotations.Count), $"Number of annotations is too big: {Annotations.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort)Annotations.Count); - foreach (var annotation in Annotations) + if (this.Annotations.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Annotations.Count), $"Number of annotations is too big: {this.Annotations.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.Annotations.Count); + foreach (TypeAnnotationNode annotation in this.Annotations) annotation.Write(attributeDataStream, writerState, scope); return attributeDataStream.ToArray(); @@ -29,11 +29,11 @@ internal class RuntimeInvisibleTypeAnnotationsAttributeFactory : ICustomAttribut { public RuntimeInvisibleTypeAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { - var attribute = new RuntimeInvisibleTypeAnnotationsAttribute(); + RuntimeInvisibleTypeAnnotationsAttribute attribute = new RuntimeInvisibleTypeAnnotationsAttribute(); - var annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.Annotations.Capacity = annotationsCount; - for (var i = 0; i < annotationsCount; i++) + for (int i = 0; i < annotationsCount; i++) attribute.Annotations.Add(TypeAnnotationNode.Parse(attributeDataStream, readerState, scope)); return attribute; diff --git a/JavaAsm/CustomAttributes/RuntimeVisibleAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeVisibleAnnotationsAttribute.cs index 87da637..24dabf7 100644 --- a/JavaAsm/CustomAttributes/RuntimeVisibleAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeVisibleAnnotationsAttribute.cs @@ -13,12 +13,12 @@ public class RuntimeVisibleAnnotationsAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - if (Annotations.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Annotations.Count), $"Number of annotations is too big: {Annotations.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort)Annotations.Count); - foreach (var annotation in Annotations) + if (this.Annotations.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Annotations.Count), $"Number of annotations is too big: {this.Annotations.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.Annotations.Count); + foreach (AnnotationNode annotation in this.Annotations) annotation.Write(attributeDataStream, writerState); return attributeDataStream.ToArray(); @@ -29,11 +29,11 @@ internal class RuntimeVisibleAnnotationsAttributeFactory : ICustomAttributeFacto { public RuntimeVisibleAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { - var attribute = new RuntimeVisibleAnnotationsAttribute(); + RuntimeVisibleAnnotationsAttribute attribute = new RuntimeVisibleAnnotationsAttribute(); - var annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.Annotations.Capacity = annotationsCount; - for (var i = 0; i < annotationsCount; i++) + for (int i = 0; i < annotationsCount; i++) attribute.Annotations.Add(AnnotationNode.Parse(attributeDataStream, readerState)); return attribute; diff --git a/JavaAsm/CustomAttributes/RuntimeVisibleParameterAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeVisibleParameterAnnotationsAttribute.cs index 4ee7947..707c8d2 100644 --- a/JavaAsm/CustomAttributes/RuntimeVisibleParameterAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeVisibleParameterAnnotationsAttribute.cs @@ -9,23 +9,23 @@ namespace JavaAsm.CustomAttributes { public class RuntimeVisibleParameterAnnotationsAttribute : CustomAttribute - { + { public List Parameters { get; set; } = new List(); internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - if (Parameters.Count > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Parameters.Count), $"Number of parameters is too big: {Parameters.Count} > {byte.MaxValue}"); - attributeDataStream.WriteByte((byte)Parameters.Count); - foreach (var parameter in Parameters) + if (this.Parameters.Count > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Parameters.Count), $"Number of parameters is too big: {this.Parameters.Count} > {byte.MaxValue}"); + attributeDataStream.WriteByte((byte) this.Parameters.Count); + foreach (ParameterAnnotations parameter in this.Parameters) { if (parameter.Annotations.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(parameter.Annotations.Count), $"Number of annotations is too big: {parameter.Annotations.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(attributeDataStream, (ushort) parameter.Annotations.Count); - foreach (var annotation in parameter.Annotations) + foreach (AnnotationNode annotation in parameter.Annotations) annotation.Write(attributeDataStream, writerState); } @@ -37,16 +37,16 @@ internal class RuntimeVisibleParameterAnnotationsAttributeFactory : ICustomAttri { public RuntimeVisibleParameterAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { - var attribute = new RuntimeVisibleParameterAnnotationsAttribute(); + RuntimeVisibleParameterAnnotationsAttribute attribute = new RuntimeVisibleParameterAnnotationsAttribute(); - var parametersCount = attributeDataStream.ReadByteFully(); + byte parametersCount = attributeDataStream.ReadByteFully(); attribute.Parameters.Capacity = parametersCount; - for (var i = 0; i < parametersCount; i++) + for (int i = 0; i < parametersCount; i++) { - var parameter = new ParameterAnnotations(); - var annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); + ParameterAnnotations parameter = new ParameterAnnotations(); + ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); parameter.Annotations.Capacity = annotationsCount; - for (var j = 0; j < annotationsCount; j++) + for (int j = 0; j < annotationsCount; j++) parameter.Annotations.Add(AnnotationNode.Parse(attributeDataStream, readerState)); attribute.Parameters.Add(parameter); } diff --git a/JavaAsm/CustomAttributes/RuntimeVisibleTypeAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeVisibleTypeAnnotationsAttribute.cs index 67c8dd8..a342fb1 100644 --- a/JavaAsm/CustomAttributes/RuntimeVisibleTypeAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeVisibleTypeAnnotationsAttribute.cs @@ -13,15 +13,15 @@ public class RuntimeVisibleTypeAnnotationsAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + using (MemoryStream attributeDataStream = new MemoryStream()) { + if (this.Annotations.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Annotations.Count), $"Number of annotations is too big: {this.Annotations.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.Annotations.Count); + foreach (TypeAnnotationNode annotation in this.Annotations) + annotation.Write(attributeDataStream, writerState, scope); - if (Annotations.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Annotations.Count), $"Number of annotations is too big: {Annotations.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort)Annotations.Count); - foreach (var annotation in Annotations) - annotation.Write(attributeDataStream, writerState, scope); - - return attributeDataStream.ToArray(); + return attributeDataStream.ToArray(); + } } } @@ -29,11 +29,11 @@ internal class RuntimeVisibleTypeAnnotationsAttributeFactory : ICustomAttributeF { public RuntimeVisibleTypeAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { - var attribute = new RuntimeVisibleTypeAnnotationsAttribute(); + RuntimeVisibleTypeAnnotationsAttribute attribute = new RuntimeVisibleTypeAnnotationsAttribute(); - var annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.Annotations.Capacity = annotationsCount; - for (var i = 0; i < annotationsCount; i++) + for (int i = 0; i < annotationsCount; i++) attribute.Annotations.Add(TypeAnnotationNode.Parse(attributeDataStream, readerState, scope)); return attribute; diff --git a/JavaAsm/CustomAttributes/SignatureAttribute.cs b/JavaAsm/CustomAttributes/SignatureAttribute.cs index 184e647..c8dd174 100644 --- a/JavaAsm/CustomAttributes/SignatureAttribute.cs +++ b/JavaAsm/CustomAttributes/SignatureAttribute.cs @@ -11,9 +11,9 @@ public class SignatureAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new Utf8Entry(Value))); + Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new Utf8Entry(this.Value))); return attributeDataStream.ToArray(); } diff --git a/JavaAsm/CustomAttributes/SourceDebugExtensionAttribute.cs b/JavaAsm/CustomAttributes/SourceDebugExtensionAttribute.cs index 37b56ca..bead31d 100644 --- a/JavaAsm/CustomAttributes/SourceDebugExtensionAttribute.cs +++ b/JavaAsm/CustomAttributes/SourceDebugExtensionAttribute.cs @@ -10,7 +10,7 @@ public class SourceDebugExtensionAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - return ModifiedUtf8Helper.Encode(Value); + return ModifiedUtf8Helper.Encode(this.Value); } } diff --git a/JavaAsm/CustomAttributes/SourceFileAttribute.cs b/JavaAsm/CustomAttributes/SourceFileAttribute.cs index bf0bb61..d9487ff 100644 --- a/JavaAsm/CustomAttributes/SourceFileAttribute.cs +++ b/JavaAsm/CustomAttributes/SourceFileAttribute.cs @@ -11,9 +11,9 @@ public class SourceFileAttribute : CustomAttribute internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new Utf8Entry(Value))); + Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new Utf8Entry(this.Value))); return attributeDataStream.ToArray(); } @@ -23,7 +23,7 @@ internal class SourceFileAttributeFactory : ICustomAttributeFactory(Binary.BigEndian.ReadUInt16(attributeDataStream)).String }; diff --git a/JavaAsm/CustomAttributes/StackMapTableAttribute.cs b/JavaAsm/CustomAttributes/StackMapTableAttribute.cs index 69eb509..913c9c9 100644 --- a/JavaAsm/CustomAttributes/StackMapTableAttribute.cs +++ b/JavaAsm/CustomAttributes/StackMapTableAttribute.cs @@ -36,7 +36,7 @@ public SimpleVerificationElement(VerificationElementType type) { type.CheckInAndThrow(nameof(type), VerificationElementType.Top, VerificationElementType.Integer, VerificationElementType.Float, VerificationElementType.Long, VerificationElementType.Double, VerificationElementType.Null, VerificationElementType.UnitializedThis); - Type = type; + this.Type = type; } } @@ -100,14 +100,14 @@ internal static void WriteVerificationElement(Stream stream, ClassWriterState wr internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { - using var attributeDataStream = new MemoryStream(); + MemoryStream attributeDataStream = new MemoryStream(); - if (Entries.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Entries.Count), $"Too many entries for StackMapTable: {Entries.Count} > {ushort.MaxValue}"); + if (this.Entries.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Entries.Count), $"Too many entries for StackMapTable: {this.Entries.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort) Entries.Count); + Binary.BigEndian.Write(attributeDataStream, (ushort) this.Entries.Count); - foreach (var entry in Entries) + foreach (StackMapFrame entry in this.Entries) { switch (entry.Type) { @@ -147,7 +147,7 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope $"Number of locals was < 1 || > 3: {entry.Locals}"); attributeDataStream.WriteByte((byte) (251 + entry.Locals.Count)); Binary.BigEndian.Write(attributeDataStream, entry.OffsetDelta); - foreach (var verificationElement in entry.Locals) + foreach (VerificationElement verificationElement in entry.Locals) WriteVerificationElement(attributeDataStream, writerState, verificationElement); break; case FrameType.Full: @@ -158,14 +158,14 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope throw new ArgumentOutOfRangeException(nameof(entry.Locals.Count), $"Too many entries in frame's locals: {entry.Locals.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(attributeDataStream, (ushort) entry.Locals.Count); - foreach (var verificationElement in entry.Locals) + foreach (VerificationElement verificationElement in entry.Locals) WriteVerificationElement(attributeDataStream, writerState, verificationElement); if (entry.Stack.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(entry.Stack.Count), $"Too many entries in frame's stack: {entry.Stack.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(attributeDataStream, (ushort) entry.Stack.Count); - foreach (var verificationElement in entry.Stack) + foreach (VerificationElement verificationElement in entry.Stack) WriteVerificationElement(attributeDataStream, writerState, verificationElement); break; default: @@ -179,42 +179,33 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope internal class StackMapTableAttributeFactory : ICustomAttributeFactory { - private static StackMapTableAttribute.VerificationElement ReadVerificationElement(Stream stream, ClassReaderState readerState) - { - var verificationElementType = (StackMapTableAttribute.VerificationElementType) stream.ReadByteFully(); - return verificationElementType switch - { - StackMapTableAttribute.VerificationElementType.Top => (StackMapTableAttribute.VerificationElement) new StackMapTableAttribute.SimpleVerificationElement(verificationElementType), - StackMapTableAttribute.VerificationElementType.Integer => new StackMapTableAttribute.SimpleVerificationElement(verificationElementType), - StackMapTableAttribute.VerificationElementType.Float => new StackMapTableAttribute.SimpleVerificationElement(verificationElementType), - StackMapTableAttribute.VerificationElementType.Long => new StackMapTableAttribute.SimpleVerificationElement(verificationElementType), - StackMapTableAttribute.VerificationElementType.Double => new StackMapTableAttribute.SimpleVerificationElement(verificationElementType), - StackMapTableAttribute.VerificationElementType.Null => new StackMapTableAttribute.SimpleVerificationElement(verificationElementType), - StackMapTableAttribute.VerificationElementType.UnitializedThis => new StackMapTableAttribute.SimpleVerificationElement(verificationElementType), - StackMapTableAttribute.VerificationElementType.Object => new StackMapTableAttribute.ObjectVerificationElement - { - ObjectClass = new ClassName(readerState.ConstantPool - .GetEntry(Binary.BigEndian.ReadUInt16(stream)) - .Name.String) - }, - StackMapTableAttribute.VerificationElementType.Unitialized => new StackMapTableAttribute.UninitializedVerificationElement - { - NewInstructionOffset = Binary.BigEndian.ReadUInt16(stream) - }, - _ => throw new ArgumentOutOfRangeException(nameof(verificationElementType)) - }; + private static StackMapTableAttribute.VerificationElement ReadVerificationElement(Stream stream, ClassReaderState readerState) { + StackMapTableAttribute.VerificationElementType verificationElementType = (StackMapTableAttribute.VerificationElementType) stream.ReadByteFully(); + switch (verificationElementType) { + case StackMapTableAttribute.VerificationElementType.Top: return new StackMapTableAttribute.SimpleVerificationElement(verificationElementType); + case StackMapTableAttribute.VerificationElementType.Integer: + case StackMapTableAttribute.VerificationElementType.Float: + case StackMapTableAttribute.VerificationElementType.Long: + case StackMapTableAttribute.VerificationElementType.Double: + case StackMapTableAttribute.VerificationElementType.Null: + case StackMapTableAttribute.VerificationElementType.UnitializedThis: + return new StackMapTableAttribute.SimpleVerificationElement(verificationElementType); + case StackMapTableAttribute.VerificationElementType.Object: return new StackMapTableAttribute.ObjectVerificationElement {ObjectClass = new ClassName(readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).Name.String)}; + case StackMapTableAttribute.VerificationElementType.Unitialized: return new StackMapTableAttribute.UninitializedVerificationElement {NewInstructionOffset = Binary.BigEndian.ReadUInt16(stream)}; + default: throw new ArgumentOutOfRangeException(nameof(verificationElementType)); + } } public StackMapTableAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { - var attribute = new StackMapTableAttribute(); + StackMapTableAttribute attribute = new StackMapTableAttribute(); - var stackMapTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); + ushort stackMapTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.Entries.Capacity = stackMapTableSize; - for (var i = 0; i < stackMapTableSize; i++) + for (int i = 0; i < stackMapTableSize; i++) { StackMapTableAttribute.StackMapFrame stackMapFrame; - var frameTypeByte = attributeDataStream.ReadByteFully(); + byte frameTypeByte = attributeDataStream.ReadByteFully(); if (frameTypeByte < 64) { stackMapFrame = new StackMapTableAttribute.StackMapFrame @@ -222,7 +213,7 @@ public StackMapTableAttribute Parse(Stream attributeDataStream, uint attributeDa Type = StackMapTableAttribute.FrameType.Same, OffsetDelta = frameTypeByte }; - } + } else if (frameTypeByte < 128) { stackMapFrame = new StackMapTableAttribute.StackMapFrame @@ -268,7 +259,7 @@ public StackMapTableAttribute Parse(Stream attributeDataStream, uint attributeDa OffsetDelta = Binary.BigEndian.ReadUInt16(attributeDataStream) }; - for (var j = 0; j < frameTypeByte - 251; j++) + for (int j = 0; j < frameTypeByte - 251; j++) { stackMapFrame.Locals.Add(ReadVerificationElement(attributeDataStream, readerState)); } @@ -281,11 +272,11 @@ public StackMapTableAttribute Parse(Stream attributeDataStream, uint attributeDa OffsetDelta = Binary.BigEndian.ReadUInt16(attributeDataStream) }; - var localsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); - for (var j = 0; j < localsCount; j++) + ushort localsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); + for (int j = 0; j < localsCount; j++) stackMapFrame.Locals.Add(ReadVerificationElement(attributeDataStream, readerState)); - var stackCount = Binary.BigEndian.ReadUInt16(attributeDataStream); - for (var j = 0; j < stackCount; j++) + ushort stackCount = Binary.BigEndian.ReadUInt16(attributeDataStream); + for (int j = 0; j < stackCount; j++) stackMapFrame.Stack.Add(ReadVerificationElement(attributeDataStream, readerState)); } else diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/CatchTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/CatchTarget.cs index 352b598..0a9a85d 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/CatchTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/CatchTarget.cs @@ -12,12 +12,12 @@ public class CatchTarget : TypeAnnotationTarget internal override void Write(Stream stream, ClassWriterState writerState) { - Binary.BigEndian.Write(stream, ExceptionTableIndex); + Binary.BigEndian.Write(stream, this.ExceptionTableIndex); } internal override void Read(Stream stream, ClassReaderState readerState) { - ExceptionTableIndex = Binary.BigEndian.ReadUInt16(stream); + this.ExceptionTableIndex = Binary.BigEndian.ReadUInt16(stream); } } } \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/FormalParameterTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/FormalParameterTarget.cs index a697871..da2fae4 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/FormalParameterTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/FormalParameterTarget.cs @@ -12,12 +12,12 @@ public class FormalParameterTarget : TypeAnnotationTarget internal override void Write(Stream stream, ClassWriterState writerState) { - stream.WriteByte(FormalParameterIndex); + stream.WriteByte(this.FormalParameterIndex); } internal override void Read(Stream stream, ClassReaderState readerState) { - FormalParameterIndex = stream.ReadByteFully(); + this.FormalParameterIndex = stream.ReadByteFully(); } } } \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/LocalvarTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/LocalvarTarget.cs index d6d4eb9..c6caa98 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/LocalvarTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/LocalvarTarget.cs @@ -23,10 +23,10 @@ public class TableEntry internal override void Write(Stream stream, ClassWriterState writerState) { - if (Table.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Table.Count), $"Table is too big: {Table.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(stream, (ushort) Table.Count); - foreach (var entry in Table) + if (this.Table.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Table.Count), $"Table is too big: {this.Table.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(stream, (ushort) this.Table.Count); + foreach (TableEntry entry in this.Table) { Binary.BigEndian.Write(stream, entry.StartPc); Binary.BigEndian.Write(stream, entry.Length); @@ -36,11 +36,11 @@ internal override void Write(Stream stream, ClassWriterState writerState) internal override void Read(Stream stream, ClassReaderState readerState) { - var tableSize = Binary.BigEndian.ReadUInt16(stream); - Table.Capacity = tableSize; - for (var i = 0; i < tableSize; i++) + ushort tableSize = Binary.BigEndian.ReadUInt16(stream); + this.Table.Capacity = tableSize; + for (int i = 0; i < tableSize; i++) { - Table.Add(new TableEntry + this.Table.Add(new TableEntry { StartPc = Binary.BigEndian.ReadUInt16(stream), Length = Binary.BigEndian.ReadUInt16(stream), diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/OffsetTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/OffsetTarget.cs index 1c0684b..a7303c8 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/OffsetTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/OffsetTarget.cs @@ -12,12 +12,12 @@ public class OffsetTarget : TypeAnnotationTarget internal override void Write(Stream stream, ClassWriterState writerState) { - Binary.BigEndian.Write(stream, Offset); + Binary.BigEndian.Write(stream, this.Offset); } internal override void Read(Stream stream, ClassReaderState readerState) { - Offset = Binary.BigEndian.ReadUInt16(stream); + this.Offset = Binary.BigEndian.ReadUInt16(stream); } } } \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/SupertypeTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/SupertypeTarget.cs index 42b86ae..6fd6d97 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/SupertypeTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/SupertypeTarget.cs @@ -12,12 +12,12 @@ public class SupertypeTarget : TypeAnnotationTarget internal override void Write(Stream stream, ClassWriterState writerState) { - Binary.BigEndian.Write(stream, SupertypeIndex); + Binary.BigEndian.Write(stream, this.SupertypeIndex); } internal override void Read(Stream stream, ClassReaderState readerState) { - SupertypeIndex = Binary.BigEndian.ReadUInt16(stream); + this.SupertypeIndex = Binary.BigEndian.ReadUInt16(stream); } } } \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TargetType.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TargetType.cs index 4c342a1..9284b15 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TargetType.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TargetType.cs @@ -14,7 +14,7 @@ public enum TargetType ReceiverTypeOfMethodOrConstructor = 0x15, TypeInFormalParameterOfMethodOrConstructorOrLambda = 0x16, ThrowsClause = 0x17, - + LocalVariableDeclaration = 0x40, ResourceVariableDeclaration = 0x41, ExceptionParameterDeclaration = 0x42, diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/ThrowsTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/ThrowsTarget.cs index a27cb42..24ec1aa 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/ThrowsTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/ThrowsTarget.cs @@ -12,12 +12,12 @@ public class ThrowsTarget : TypeAnnotationTarget internal override void Write(Stream stream, ClassWriterState writerState) { - Binary.BigEndian.Write(stream, ThrowsTypeIndex); + Binary.BigEndian.Write(stream, this.ThrowsTypeIndex); } internal override void Read(Stream stream, ClassReaderState readerState) { - ThrowsTypeIndex = Binary.BigEndian.ReadUInt16(stream); + this.ThrowsTypeIndex = Binary.BigEndian.ReadUInt16(stream); } } } \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationNode.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationNode.cs index 6e763d9..8b7eff7 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationNode.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationNode.cs @@ -30,42 +30,64 @@ public class ElementValuePair internal static TypeAnnotationNode Parse(Stream stream, ClassReaderState readerState, AttributeScope scope) { - var typeAnnotation = new TypeAnnotationNode + TypeAnnotationNode typeAnnotation = new TypeAnnotationNode { TargetType = (TargetType) stream.ReadByteFully() }; - typeAnnotation.Target = typeAnnotation.TargetType switch - { - TargetType.GenericClassOrInterfaceDeclaration when scope == AttributeScope.Class => (TypeAnnotationTarget) new TypeParameterTarget(), - TargetType.GenericMethodOrConstructorDeclaration when scope == AttributeScope.Method => new TypeParameterTarget(), - TargetType.ExtendsOrImplements when scope == AttributeScope.Class => new SupertypeTarget(), - TargetType.TypeInBoundInGenericClassOrInterface when scope == AttributeScope.Class => new TypeParameterBoundTarget(), - TargetType.TypeInBoundInGenericMethodOrConstructor when scope == AttributeScope.Method => new TypeParameterBoundTarget(), - TargetType.FieldDeclaration when scope == AttributeScope.Field => new EmptyTarget(), - TargetType.ReturnTypeOrNewObject when scope == AttributeScope.Method => new EmptyTarget(), - TargetType.ReceiverTypeOfMethodOrConstructor when scope == AttributeScope.Method => new EmptyTarget(), - TargetType.TypeInFormalParameterOfMethodOrConstructorOrLambda when scope == AttributeScope.Method => new FormalParameterTarget(), - TargetType.ThrowsClause when scope == AttributeScope.Method => new ThrowsTarget(), - TargetType.LocalVariableDeclaration when scope == AttributeScope.Code => new LocalvarTarget(), - TargetType.ResourceVariableDeclaration when scope == AttributeScope.Code => new LocalvarTarget(), - TargetType.ExceptionParameterDeclaration when scope == AttributeScope.Code => new CatchTarget(), - TargetType.InstanceOfExpression when scope == AttributeScope.Code => new OffsetTarget(), - TargetType.NewExpression when scope == AttributeScope.Code => new OffsetTarget(), - TargetType.MethodReferenceExpressionNew when scope == AttributeScope.Code => new OffsetTarget(), - TargetType.MethodReferenceExpressionIdentifier when scope == AttributeScope.Code => new OffsetTarget(), - TargetType.CastExpression when scope == AttributeScope.Code => new TypeArgumentTarget(), - TargetType.ArgumentForGenericConstructorInvocation when scope == AttributeScope.Code => new TypeArgumentTarget(), - TargetType.ArgumentForGenericMethodInvocation when scope == AttributeScope.Code => new TypeArgumentTarget(), - TargetType.ArgumentForGenericMethodReferenceExpressionNew when scope == AttributeScope.Code => new TypeArgumentTarget(), - TargetType.ArgumentForGenericMethodReferenceExpressionIdentifier when scope == AttributeScope.Code => new TypeArgumentTarget(), - _ => throw new ArgumentOutOfRangeException(nameof(TargetType)) - }; + switch (typeAnnotation.TargetType) { + case TargetType.GenericClassOrInterfaceDeclaration when scope == AttributeScope.Class: + typeAnnotation.Target = new TypeParameterTarget(); + break; + case TargetType.GenericMethodOrConstructorDeclaration when scope == AttributeScope.Method: + typeAnnotation.Target = new TypeParameterTarget(); + break; + case TargetType.ExtendsOrImplements when scope == AttributeScope.Class: + typeAnnotation.Target = new SupertypeTarget(); + break; + case TargetType.TypeInBoundInGenericClassOrInterface when scope == AttributeScope.Class: + case TargetType.TypeInBoundInGenericMethodOrConstructor when scope == AttributeScope.Method: + typeAnnotation.Target = new TypeParameterBoundTarget(); + break; + case TargetType.FieldDeclaration when scope == AttributeScope.Field: + case TargetType.ReturnTypeOrNewObject when scope == AttributeScope.Method: + case TargetType.ReceiverTypeOfMethodOrConstructor when scope == AttributeScope.Method: + typeAnnotation.Target = new EmptyTarget(); + break; + case TargetType.TypeInFormalParameterOfMethodOrConstructorOrLambda when scope == AttributeScope.Method: + typeAnnotation.Target = new FormalParameterTarget(); + break; + case TargetType.ThrowsClause when scope == AttributeScope.Method: + typeAnnotation.Target = new ThrowsTarget(); + break; + case TargetType.LocalVariableDeclaration when scope == AttributeScope.Code: + case TargetType.ResourceVariableDeclaration when scope == AttributeScope.Code: + typeAnnotation.Target = new LocalvarTarget(); + break; + case TargetType.ExceptionParameterDeclaration when scope == AttributeScope.Code: + typeAnnotation.Target = new CatchTarget(); + break; + case TargetType.InstanceOfExpression when scope == AttributeScope.Code: + case TargetType.NewExpression when scope == AttributeScope.Code: + case TargetType.MethodReferenceExpressionNew when scope == AttributeScope.Code: + case TargetType.MethodReferenceExpressionIdentifier when scope == AttributeScope.Code: + typeAnnotation.Target = new OffsetTarget(); + break; + case TargetType.CastExpression when scope == AttributeScope.Code: + case TargetType.ArgumentForGenericConstructorInvocation when scope == AttributeScope.Code: + case TargetType.ArgumentForGenericMethodInvocation when scope == AttributeScope.Code: + case TargetType.ArgumentForGenericMethodReferenceExpressionNew when scope == AttributeScope.Code: + case TargetType.ArgumentForGenericMethodReferenceExpressionIdentifier when scope == AttributeScope.Code: + typeAnnotation.Target = new TypeArgumentTarget(); + break; + default: throw new ArgumentOutOfRangeException(nameof(TargetType)); + } + typeAnnotation.Target.Read(stream, readerState); typeAnnotation.TypePath = new TypePath(); typeAnnotation.TypePath.Read(stream, readerState); - var elementValuePairsCount = Binary.BigEndian.ReadUInt16(stream); + ushort elementValuePairsCount = Binary.BigEndian.ReadUInt16(stream); typeAnnotation.ElementValuePairs.Capacity = elementValuePairsCount; - for (var i = 0; i < elementValuePairsCount; i++) + for (int i = 0; i < elementValuePairsCount; i++) typeAnnotation.ElementValuePairs.Add(new ElementValuePair { ElementName = readerState.ConstantPool @@ -77,44 +99,44 @@ internal static TypeAnnotationNode Parse(Stream stream, ClassReaderState readerS internal void Write(Stream stream, ClassWriterState writerState, AttributeScope scope) { - stream.WriteByte((byte) TargetType); - switch (TargetType) + stream.WriteByte((byte) this.TargetType); + switch (this.TargetType) { - case TargetType.GenericClassOrInterfaceDeclaration when Target.TargetTypeKind == TargetTypeKind.TypeParameter && scope == AttributeScope.Class: - case TargetType.GenericMethodOrConstructorDeclaration when Target.TargetTypeKind == TargetTypeKind.TypeParameter && scope == AttributeScope.Method: - case TargetType.ExtendsOrImplements when Target.TargetTypeKind == TargetTypeKind.Supertype && scope == AttributeScope.Class: - case TargetType.TypeInBoundInGenericClassOrInterface when Target.TargetTypeKind == TargetTypeKind.TypeParameterBound && scope == AttributeScope.Class: - case TargetType.TypeInBoundInGenericMethodOrConstructor when Target.TargetTypeKind == TargetTypeKind.TypeParameterBound && scope == AttributeScope.Method: - case TargetType.FieldDeclaration when Target.TargetTypeKind == TargetTypeKind.Empty && scope == AttributeScope.Field: - case TargetType.ReturnTypeOrNewObject when Target.TargetTypeKind == TargetTypeKind.Empty && scope == AttributeScope.Method: - case TargetType.ReceiverTypeOfMethodOrConstructor when Target.TargetTypeKind == TargetTypeKind.Empty && scope == AttributeScope.Method: - case TargetType.TypeInFormalParameterOfMethodOrConstructorOrLambda when Target.TargetTypeKind == TargetTypeKind.FormalParameter && scope == AttributeScope.Method: - case TargetType.ThrowsClause when Target.TargetTypeKind == TargetTypeKind.Throws && scope == AttributeScope.Method: - case TargetType.LocalVariableDeclaration when Target.TargetTypeKind == TargetTypeKind.Localvar && scope == AttributeScope.Code: - case TargetType.ResourceVariableDeclaration when Target.TargetTypeKind == TargetTypeKind.Localvar && scope == AttributeScope.Code: - case TargetType.ExceptionParameterDeclaration when Target.TargetTypeKind == TargetTypeKind.Catch && scope == AttributeScope.Code: - case TargetType.InstanceOfExpression when Target.TargetTypeKind == TargetTypeKind.Offset && scope == AttributeScope.Code: - case TargetType.NewExpression when Target.TargetTypeKind == TargetTypeKind.Offset && scope == AttributeScope.Code: - case TargetType.MethodReferenceExpressionNew when Target.TargetTypeKind == TargetTypeKind.Offset && scope == AttributeScope.Code: - case TargetType.MethodReferenceExpressionIdentifier when Target.TargetTypeKind == TargetTypeKind.Offset && scope == AttributeScope.Code: - case TargetType.CastExpression when Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: - case TargetType.ArgumentForGenericConstructorInvocation when Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: - case TargetType.ArgumentForGenericMethodInvocation when Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: - case TargetType.ArgumentForGenericMethodReferenceExpressionNew when Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: - case TargetType.ArgumentForGenericMethodReferenceExpressionIdentifier when Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: - Target.Write(stream, writerState); + case TargetType.GenericClassOrInterfaceDeclaration when this.Target.TargetTypeKind == TargetTypeKind.TypeParameter && scope == AttributeScope.Class: + case TargetType.GenericMethodOrConstructorDeclaration when this.Target.TargetTypeKind == TargetTypeKind.TypeParameter && scope == AttributeScope.Method: + case TargetType.ExtendsOrImplements when this.Target.TargetTypeKind == TargetTypeKind.Supertype && scope == AttributeScope.Class: + case TargetType.TypeInBoundInGenericClassOrInterface when this.Target.TargetTypeKind == TargetTypeKind.TypeParameterBound && scope == AttributeScope.Class: + case TargetType.TypeInBoundInGenericMethodOrConstructor when this.Target.TargetTypeKind == TargetTypeKind.TypeParameterBound && scope == AttributeScope.Method: + case TargetType.FieldDeclaration when this.Target.TargetTypeKind == TargetTypeKind.Empty && scope == AttributeScope.Field: + case TargetType.ReturnTypeOrNewObject when this.Target.TargetTypeKind == TargetTypeKind.Empty && scope == AttributeScope.Method: + case TargetType.ReceiverTypeOfMethodOrConstructor when this.Target.TargetTypeKind == TargetTypeKind.Empty && scope == AttributeScope.Method: + case TargetType.TypeInFormalParameterOfMethodOrConstructorOrLambda when this.Target.TargetTypeKind == TargetTypeKind.FormalParameter && scope == AttributeScope.Method: + case TargetType.ThrowsClause when this.Target.TargetTypeKind == TargetTypeKind.Throws && scope == AttributeScope.Method: + case TargetType.LocalVariableDeclaration when this.Target.TargetTypeKind == TargetTypeKind.Localvar && scope == AttributeScope.Code: + case TargetType.ResourceVariableDeclaration when this.Target.TargetTypeKind == TargetTypeKind.Localvar && scope == AttributeScope.Code: + case TargetType.ExceptionParameterDeclaration when this.Target.TargetTypeKind == TargetTypeKind.Catch && scope == AttributeScope.Code: + case TargetType.InstanceOfExpression when this.Target.TargetTypeKind == TargetTypeKind.Offset && scope == AttributeScope.Code: + case TargetType.NewExpression when this.Target.TargetTypeKind == TargetTypeKind.Offset && scope == AttributeScope.Code: + case TargetType.MethodReferenceExpressionNew when this.Target.TargetTypeKind == TargetTypeKind.Offset && scope == AttributeScope.Code: + case TargetType.MethodReferenceExpressionIdentifier when this.Target.TargetTypeKind == TargetTypeKind.Offset && scope == AttributeScope.Code: + case TargetType.CastExpression when this.Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: + case TargetType.ArgumentForGenericConstructorInvocation when this.Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: + case TargetType.ArgumentForGenericMethodInvocation when this.Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: + case TargetType.ArgumentForGenericMethodReferenceExpressionNew when this.Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: + case TargetType.ArgumentForGenericMethodReferenceExpressionIdentifier when this.Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: + this.Target.Write(stream, writerState); break; default: - throw new ArgumentOutOfRangeException(nameof(TargetType)); + throw new ArgumentOutOfRangeException(nameof(this.TargetType)); } - TypePath.Write(stream, writerState); + this.TypePath.Write(stream, writerState); - if (ElementValuePairs.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(ElementValuePairs.Count), - $"Too many ElementValues: {ElementValuePairs.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(stream, (ushort)ElementValuePairs.Count); - foreach (var elementValuePair in ElementValuePairs) + if (this.ElementValuePairs.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.ElementValuePairs.Count), + $"Too many ElementValues: {this.ElementValuePairs.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(stream, (ushort) this.ElementValuePairs.Count); + foreach (ElementValuePair elementValuePair in this.ElementValuePairs) { Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new Utf8Entry(elementValuePair.ElementName))); diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypeArgumentTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypeArgumentTarget.cs index 608ca01..1da5498 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypeArgumentTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypeArgumentTarget.cs @@ -15,14 +15,14 @@ public class TypeArgumentTarget : TypeAnnotationTarget internal override void Write(Stream stream, ClassWriterState writerState) { - Binary.BigEndian.Write(stream, Offset); - stream.WriteByte(TypeArgumentIndex); + Binary.BigEndian.Write(stream, this.Offset); + stream.WriteByte(this.TypeArgumentIndex); } internal override void Read(Stream stream, ClassReaderState readerState) { - Offset = Binary.BigEndian.ReadUInt16(stream); - TypeArgumentIndex = stream.ReadByteFully(); + this.Offset = Binary.BigEndian.ReadUInt16(stream); + this.TypeArgumentIndex = stream.ReadByteFully(); } } } \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterBoundTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterBoundTarget.cs index 8c1d8ce..137b819 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterBoundTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterBoundTarget.cs @@ -14,14 +14,14 @@ public class TypeParameterBoundTarget : TypeAnnotationTarget internal override void Write(Stream stream, ClassWriterState writerState) { - stream.WriteByte(TypeParameterIndex); - stream.WriteByte(BoundIndex); + stream.WriteByte(this.TypeParameterIndex); + stream.WriteByte(this.BoundIndex); } internal override void Read(Stream stream, ClassReaderState readerState) { - TypeParameterIndex = stream.ReadByteFully(); - BoundIndex = stream.ReadByteFully(); + this.TypeParameterIndex = stream.ReadByteFully(); + this.BoundIndex = stream.ReadByteFully(); } } } \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterTarget.cs index d964ed3..41efdf1 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterTarget.cs @@ -12,12 +12,12 @@ public class TypeParameterTarget : TypeAnnotationTarget internal override void Write(Stream stream, ClassWriterState writerState) { - stream.WriteByte(TypeParameterIndex); + stream.WriteByte(this.TypeParameterIndex); } internal override void Read(Stream stream, ClassReaderState readerState) { - TypeParameterIndex = stream.ReadByteFully(); + this.TypeParameterIndex = stream.ReadByteFully(); } } } \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypePath.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypePath.cs index cb275de..6c6fb3f 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypePath.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypePath.cs @@ -27,11 +27,11 @@ public class PathPart internal void Read(Stream stream, ClassReaderState classReaderState) { - var pathSize = stream.ReadByteFully(); - Path.Capacity = pathSize; - for (var i = 0; i < pathSize; i++) + byte pathSize = stream.ReadByteFully(); + this.Path.Capacity = pathSize; + for (int i = 0; i < pathSize; i++) { - Path.Add(new PathPart + this.Path.Add(new PathPart { TypePathKind = (TypePathKind) stream.ReadByteFully(), TypeArgumentIndex = stream.ReadByteFully() @@ -41,10 +41,10 @@ internal void Read(Stream stream, ClassReaderState classReaderState) internal void Write(Stream stream, ClassWriterState writerState) { - if (Path.Count > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(Path.Count), $"Path is too big: {Path.Count} > {byte.MaxValue}"); - stream.WriteByte((byte) Path.Count); - foreach (var part in Path) + if (this.Path.Count > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.Path.Count), $"Path is too big: {this.Path.Count} > {byte.MaxValue}"); + stream.WriteByte((byte) this.Path.Count); + foreach (PathPart part in this.Path) { stream.WriteByte((byte) part.TypePathKind); stream.WriteByte(part.TypeArgumentIndex); diff --git a/JavaAsm/FieldNode.cs b/JavaAsm/FieldNode.cs index b8b1303..68bd93d 100644 --- a/JavaAsm/FieldNode.cs +++ b/JavaAsm/FieldNode.cs @@ -63,7 +63,7 @@ public class FieldNode /// Constant value /// public object ConstantValue { get; set; } - + /// /// Returns and deletes attribute. Used for internal methods to parse contents /// @@ -71,33 +71,33 @@ public class FieldNode /// null, if attribute does not exist or AttributeNode if exists private AttributeNode GetAttribute(string name) { - var attribute = Attributes.FirstOrDefault(a => a.Name == name); + AttributeNode attribute = this.Attributes.FirstOrDefault(a => a.Name == name); if (attribute != null) - Attributes.Remove(attribute); + this.Attributes.Remove(attribute); return attribute; } - + /// /// Parses field annotations to fill up information /// /// Class reader state internal void Parse(ClassReaderState readerState) { - Signature = (GetAttribute(PredefinedAttributeNames.Signature)?.ParsedAttribute as SignatureAttribute)?.Value; + this.Signature = (GetAttribute(PredefinedAttributeNames.Signature)?.ParsedAttribute as SignatureAttribute)?.Value; { - var attribute = GetAttribute(PredefinedAttributeNames.RuntimeInvisibleAnnotations); + AttributeNode attribute = GetAttribute(PredefinedAttributeNames.RuntimeInvisibleAnnotations); if (attribute != null) - InvisibleAnnotations = (attribute.ParsedAttribute as RuntimeInvisibleAnnotationsAttribute)?.Annotations; + this.InvisibleAnnotations = (attribute.ParsedAttribute as RuntimeInvisibleAnnotationsAttribute)?.Annotations; } { - var attribute = GetAttribute(PredefinedAttributeNames.RuntimeVisibleAnnotations); + AttributeNode attribute = GetAttribute(PredefinedAttributeNames.RuntimeVisibleAnnotations); if (attribute != null) - VisibleAnnotations = (attribute.ParsedAttribute as RuntimeVisibleAnnotationsAttribute)?.Annotations; + this.VisibleAnnotations = (attribute.ParsedAttribute as RuntimeVisibleAnnotationsAttribute)?.Annotations; } - ConstantValue = + this.ConstantValue = (GetAttribute(PredefinedAttributeNames.ConstantValue)?.ParsedAttribute as ConstantValueAttribute)?.Value; - IsDeprecated = GetAttribute(PredefinedAttributeNames.Deprecated)?.ParsedAttribute != null; + this.IsDeprecated = GetAttribute(PredefinedAttributeNames.Deprecated)?.ParsedAttribute != null; } /// @@ -106,73 +106,73 @@ internal void Parse(ClassReaderState readerState) /// Class writer state internal void Save(ClassWriterState writerState) { - if (Signature != null) + if (this.Signature != null) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.Signature)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Signature)) throw new Exception( $"{PredefinedAttributeNames.Signature} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Signature, ParsedAttribute = new SignatureAttribute { - Value = Signature + Value = this.Signature } }); } - if (InvisibleAnnotations != null && InvisibleAnnotations.Count > 0) + if (this.InvisibleAnnotations != null && this.InvisibleAnnotations.Count > 0) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeInvisibleAnnotations)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeInvisibleAnnotations)) throw new Exception( $"{PredefinedAttributeNames.RuntimeInvisibleAnnotations} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeInvisibleAnnotations, ParsedAttribute = new RuntimeInvisibleAnnotationsAttribute { - Annotations = InvisibleAnnotations + Annotations = this.InvisibleAnnotations } }); } - if (VisibleAnnotations != null && VisibleAnnotations.Count > 0) + if (this.VisibleAnnotations != null && this.VisibleAnnotations.Count > 0) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeVisibleAnnotations)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeVisibleAnnotations)) throw new Exception( $"{PredefinedAttributeNames.RuntimeVisibleAnnotations} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeVisibleAnnotations, ParsedAttribute = new RuntimeVisibleAnnotationsAttribute { - Annotations = VisibleAnnotations + Annotations = this.VisibleAnnotations } }); } - if (ConstantValue != null) + if (this.ConstantValue != null) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.ConstantValue)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.ConstantValue)) throw new Exception( $"{PredefinedAttributeNames.ConstantValue} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.ConstantValue, ParsedAttribute = new ConstantValueAttribute { - Value = ConstantValue + Value = this.ConstantValue } }); } // ReSharper disable once InvertIf - if (IsDeprecated) + if (this.IsDeprecated) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.Deprecated)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Deprecated)) throw new Exception( $"{PredefinedAttributeNames.Deprecated} attribute is already presented on field"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Deprecated, ParsedAttribute = new DeprecatedAttribute() @@ -183,7 +183,7 @@ internal void Save(ClassWriterState writerState) /// public override string ToString() { - return $"{AccessModifiersExtensions.ToString(Access)} {Descriptor} {Name}"; + return $"{AccessModifiersExtensions.ToString(this.Access)} {this.Descriptor} {this.Name}"; } } } \ No newline at end of file diff --git a/JavaAsm/Helpers/Extensions.cs b/JavaAsm/Helpers/Extensions.cs index 1c02c8f..4b3548b 100644 --- a/JavaAsm/Helpers/Extensions.cs +++ b/JavaAsm/Helpers/Extensions.cs @@ -4,56 +4,61 @@ using System.Linq; using JavaAsm.Instructions.Types; -namespace JavaAsm.Helpers -{ - internal static class Extensions - { - public static bool In(this T value, params T[] values) - { +namespace JavaAsm.Helpers { + internal static class Extensions { + public static bool In(this T value, params T[] values) { return values.Contains(value); } - public static void CheckInAndThrow(this T value, string valueName, params T[] values) - { + public static void CheckInAndThrow(this T value, string valueName, params T[] values) { if (!values.Contains(value)) throw new ArgumentOutOfRangeException(nameof(valueName), $"{valueName} is not in [{string.Join(", ", values)}]"); } - public static bool TryAdd(this ICollection collection, T value) - { + public static bool TryAdd(this ICollection collection, T value) { if (collection.Contains(value)) return false; collection.Add(value); return true; } + + public static bool TryAdd(this IDictionary collection, K key, V value) { + if (collection.ContainsKey(key)) + return false; + collection[key] = value; + return true; + } } - internal static class StreamExtensions - { - public static byte ReadByteFully(this Stream stream) - { + internal static class StreamExtensions { + public static byte ReadByteFully(this Stream stream) { return stream.ReadBytes(1)[0]; } - public static byte[] ReadBytes(this Stream stream, long count) - { - var buffer = new byte[count]; - var position = 0; - while (position < buffer.Length) - { - var result = stream.Read(buffer, position, buffer.Length - position); + public static byte[] ReadBytes(this Stream stream, long count) { + byte[] buffer = new byte[count]; + int position = 0; + while (position < buffer.Length) { + int result = stream.Read(buffer, position, buffer.Length - position); if (result <= 0) throw new EndOfStreamException(); position += result; } + return buffer; } + + public static void Write(this Stream stream, byte[] bytes) { + stream.Write(bytes, 0, bytes.Length); + } + + public static int Read(this Stream stream, byte[] bytes) { + return stream.Read(bytes, 0, bytes.Length); + } } - internal static class ReferenceKindTypeExtensions - { - public static bool IsMethodReference(this ReferenceKindType referenceKindType) - { + internal static class ReferenceKindTypeExtensions { + public static bool IsMethodReference(this ReferenceKindType referenceKindType) { return referenceKindType == ReferenceKindType.InvokeReference || referenceKindType == ReferenceKindType.InvokeSpecial || referenceKindType == ReferenceKindType.InvokeStatic || @@ -61,8 +66,7 @@ public static bool IsMethodReference(this ReferenceKindType referenceKindType) referenceKindType == ReferenceKindType.NewInvokeSpecial; } - public static bool IsFieldReference(this ReferenceKindType referenceKindType) - { + public static bool IsFieldReference(this ReferenceKindType referenceKindType) { return referenceKindType == ReferenceKindType.GetField || referenceKindType == ReferenceKindType.GetStatic || referenceKindType == ReferenceKindType.PutField || @@ -70,13 +74,11 @@ public static bool IsFieldReference(this ReferenceKindType referenceKindType) } } - internal static class DictionaryExtensions - { - public static TValue GetOrAdd(this Dictionary dictionary, TKey key, TValue value) - { + internal static class DictionaryExtensions { + public static TValue GetOrAdd(this Dictionary dictionary, TKey key, TValue value) { if (!dictionary.ContainsKey(key)) dictionary.Add(key, value); return dictionary[key]; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Helpers/ModifiedUtf8Helper.cs b/JavaAsm/Helpers/ModifiedUtf8Helper.cs index b2ecb38..c5dc10d 100644 --- a/JavaAsm/Helpers/ModifiedUtf8Helper.cs +++ b/JavaAsm/Helpers/ModifiedUtf8Helper.cs @@ -6,9 +6,9 @@ public static class ModifiedUtf8Helper { public static byte[] Encode(string value) { - var offset = 0; - var buffer = new byte[GetBytesCount(value)]; - foreach (var c in value) + int offset = 0; + byte[] buffer = new byte[GetBytesCount(value)]; + foreach (char c in value) { if (c != 0 && c <= 127) buffer[offset++] = (byte)c; @@ -29,8 +29,8 @@ public static byte[] Encode(string value) public static ushort GetBytesCount(string value) { - var bytesCount = 0; - foreach (var c in value) + int bytesCount = 0; + foreach (char c in value) { if (c != 0 && c <= 127) bytesCount++; @@ -47,10 +47,10 @@ public static ushort GetBytesCount(string value) public static string Decode(byte[] data) { - var length = data.Length; - var result = new char[length]; - var count = 0; - var numberOfChars = 0; + int length = data.Length; + char[] result = new char[length]; + int count = 0; + int numberOfChars = 0; while (count < length) { if ((result[numberOfChars] = (char) data[count++]) < '\u0080') diff --git a/JavaAsm/Helpers/ReadCountStream.cs b/JavaAsm/Helpers/ReadCountStream.cs index fc3a0aa..bc236dd 100644 --- a/JavaAsm/Helpers/ReadCountStream.cs +++ b/JavaAsm/Helpers/ReadCountStream.cs @@ -17,13 +17,13 @@ public ReadWriteCountStream(Stream baseStream) public override void Flush() { - baseStream.Flush(); + this.baseStream.Flush(); } public override int Read(byte[] buffer, int offset, int count) { - var result = baseStream.Read(buffer, offset, count); - ReadBytes += Math.Max(0, result); + int result = this.baseStream.Read(buffer, offset, count); + this.ReadBytes += Math.Max(0, result); return result; } @@ -33,22 +33,22 @@ public override int Read(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count) { - baseStream.Write(buffer, offset, count); - WrittenBytes += count; + this.baseStream.Write(buffer, offset, count); + this.WrittenBytes += count; } - public override bool CanRead => baseStream.CanRead; + public override bool CanRead => this.baseStream.CanRead; public override bool CanSeek => false; - public override bool CanWrite => baseStream.CanWrite; + public override bool CanWrite => this.baseStream.CanWrite; - public override long Length => baseStream.Length; + public override long Length => this.baseStream.Length; public override long Position { - get => baseStream.Position; - set => baseStream.Position = value; + get => this.baseStream.Position; + set => this.baseStream.Position = value; } } } diff --git a/JavaAsm/IO/ClassFile.cs b/JavaAsm/IO/ClassFile.cs index 4661684..857ca64 100644 --- a/JavaAsm/IO/ClassFile.cs +++ b/JavaAsm/IO/ClassFile.cs @@ -11,7 +11,7 @@ public static class ClassFile internal static AttributeNode ParseAttribute(Stream stream, ClassReaderState state, AttributeScope scope) { - var attribute = new AttributeNode + AttributeNode attribute = new AttributeNode { Name = state.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String }; @@ -21,7 +21,7 @@ internal static AttributeNode ParseAttribute(Stream stream, ClassReaderState sta private static FieldNode ParseField(Stream stream, ClassReaderState state) { - var fieldNode = new FieldNode + FieldNode fieldNode = new FieldNode { Owner = state.ClassNode, @@ -29,16 +29,16 @@ private static FieldNode ParseField(Stream stream, ClassReaderState state) Name = state.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String, Descriptor = TypeDescriptor.Parse(state.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String) }; - var attributesCount = Binary.BigEndian.ReadUInt16(stream); + ushort attributesCount = Binary.BigEndian.ReadUInt16(stream); fieldNode.Attributes.Capacity = attributesCount; - for (var i = 0; i < attributesCount; i++) + for (int i = 0; i < attributesCount; i++) fieldNode.Attributes.Add(ParseAttribute(stream, state, AttributeScope.Field)); return fieldNode; } private static MethodNode ParseMethod(Stream stream, ClassReaderState state) { - var methodNode = new MethodNode + MethodNode methodNode = new MethodNode { Owner = state.ClassNode, @@ -46,55 +46,55 @@ private static MethodNode ParseMethod(Stream stream, ClassReaderState state) Name = state.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String, Descriptor = MethodDescriptor.Parse(state.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String) }; - var attributesCount = Binary.BigEndian.ReadUInt16(stream); + ushort attributesCount = Binary.BigEndian.ReadUInt16(stream); methodNode.Attributes.Capacity = attributesCount; - for (var i = 0; i < attributesCount; i++) + for (int i = 0; i < attributesCount; i++) methodNode.Attributes.Add(ParseAttribute(stream, state, AttributeScope.Method)); return methodNode; } public static ClassNode ParseClass(Stream stream) { - var state = new ClassReaderState(); - var result = new ClassNode(); + ClassReaderState state = new ClassReaderState(); + ClassNode result = new ClassNode(); state.ClassNode = result; if (Binary.BigEndian.ReadUInt32(stream) != Magic) throw new IOException("Wrong magic in class"); - + result.MinorVersion = Binary.BigEndian.ReadUInt16(stream); result.MajorVersion = (ClassVersion) Binary.BigEndian.ReadUInt16(stream); if (result.MajorVersion > ClassVersion.Java8) throw new Exception($"Wrong Java version: {result.MajorVersion}"); - var constantPool = new ConstantPool(); + ConstantPool constantPool = new ConstantPool(); constantPool.Read(stream); state.ConstantPool = constantPool; result.Access = (ClassAccessModifiers) Binary.BigEndian.ReadUInt16(stream); - + result.Name = new ClassName(constantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).Name.String); result.SuperName = new ClassName(constantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).Name.String); - var interfacesCount = Binary.BigEndian.ReadUInt16(stream); + ushort interfacesCount = Binary.BigEndian.ReadUInt16(stream); result.Interfaces.Capacity = interfacesCount; - for (var i = 0; i < interfacesCount; i++) + for (int i = 0; i < interfacesCount; i++) result.Interfaces.Add(new ClassName(constantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).Name.String)); - var fieldsCount = Binary.BigEndian.ReadUInt16(stream); + ushort fieldsCount = Binary.BigEndian.ReadUInt16(stream); result.Fields.Capacity = fieldsCount; - for (var i = 0; i < fieldsCount; i++) + for (int i = 0; i < fieldsCount; i++) result.Fields.Add(ParseField(stream, state)); - var methodsCount = Binary.BigEndian.ReadUInt16(stream); + ushort methodsCount = Binary.BigEndian.ReadUInt16(stream); result.Methods.Capacity = methodsCount; - for (var i = 0; i < methodsCount; i++) + for (int i = 0; i < methodsCount; i++) result.Methods.Add(ParseMethod(stream, state)); - var attributesCount = Binary.BigEndian.ReadUInt16(stream); + ushort attributesCount = Binary.BigEndian.ReadUInt16(stream); result.Attributes.Capacity = attributesCount; - for (var i = 0; i < attributesCount; i++) + for (int i = 0; i < attributesCount; i++) result.Attributes.Add(ParseAttribute(stream, state, AttributeScope.Class)); result.Parse(state); @@ -109,7 +109,7 @@ internal static void WriteAttribute(Stream stream, AttributeNode attribute, Clas if (attribute.Data.LongLength > uint.MaxValue) throw new ArgumentOutOfRangeException(nameof(attribute.Data.LongLength), $"Attribute data length too big: {attribute.Data.LongLength} > {uint.MaxValue}"); Binary.BigEndian.Write(stream, (uint) attribute.Data.LongLength); - stream.Write(attribute.Data); + stream.Write(attribute.Data, 0, attribute.Data.Length); } private static void WriteField(Stream stream, FieldNode fieldNode, ClassWriterState state) @@ -120,7 +120,7 @@ private static void WriteField(Stream stream, FieldNode fieldNode, ClassWriterSt if (fieldNode.Attributes.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(fieldNode.Attributes.Count), $"Too many attributes: {fieldNode.Attributes.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(stream, (ushort) fieldNode.Attributes.Count); - foreach (var attriute in fieldNode.Attributes) + foreach (AttributeNode attriute in fieldNode.Attributes) WriteAttribute(stream, attriute, state, AttributeScope.Field); } @@ -132,7 +132,7 @@ private static void WriteMethod(Stream stream, MethodNode methodNode, ClassWrite if (methodNode.Attributes.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(methodNode.Attributes.Count), $"Too many attributes: {methodNode.Attributes.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(stream, (ushort)methodNode.Attributes.Count); - foreach (var attriute in methodNode.Attributes) + foreach (AttributeNode attriute in methodNode.Attributes) WriteAttribute(stream, attriute, state, AttributeScope.Method); } @@ -141,9 +141,9 @@ public static void WriteClass(Stream stream, ClassNode classNode) Binary.BigEndian.Write(stream, Magic); Binary.BigEndian.Write(stream, classNode.MinorVersion); Binary.BigEndian.Write(stream, (ushort) classNode.MajorVersion); - var afterConstantPoolDataStream = new MemoryStream(); - var constantPool = new ConstantPool(); - var state = new ClassWriterState + MemoryStream afterConstantPoolDataStream = new MemoryStream(); + ConstantPool constantPool = new ConstantPool(); + ClassWriterState state = new ClassWriterState { ClassNode = classNode, ConstantPool = constantPool @@ -160,30 +160,31 @@ public static void WriteClass(Stream stream, ClassNode classNode) if (classNode.Interfaces.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(classNode.Interfaces.Count), $"Too many interfaces: {classNode.Interfaces.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort) classNode.Interfaces.Count); - foreach (var interfaceClassName in classNode.Interfaces) + foreach (ClassName interfaceClassName in classNode.Interfaces) Binary.BigEndian.Write(afterConstantPoolDataStream, constantPool.Find(new ClassEntry(new Utf8Entry(interfaceClassName.Name)))); if (classNode.Fields.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(classNode.Fields.Count), $"Too many fields: {classNode.Fields.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort) classNode.Fields.Count); - foreach (var field in classNode.Fields) + foreach (FieldNode field in classNode.Fields) WriteField(afterConstantPoolDataStream, field, state); if (classNode.Methods.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(classNode.Methods.Count), $"Too many methods: {classNode.Methods.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort)classNode.Methods.Count); - foreach (var method in classNode.Methods) + foreach (MethodNode method in classNode.Methods) WriteMethod(afterConstantPoolDataStream, method, state); if (classNode.Attributes.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(classNode.Attributes.Count), $"Too many attributes: {classNode.Attributes.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort)classNode.Attributes.Count); - foreach (var attriute in classNode.Attributes) + foreach (AttributeNode attriute in classNode.Attributes) WriteAttribute(afterConstantPoolDataStream, attriute, state, AttributeScope.Class); constantPool.Write(stream); - stream.Write(afterConstantPoolDataStream.ToArray()); + byte[] data = afterConstantPoolDataStream.ToArray(); + stream.Write(data, 0, data.Length); } } } diff --git a/JavaAsm/IO/ConstantPool.cs b/JavaAsm/IO/ConstantPool.cs index 378b2c5..654ec40 100644 --- a/JavaAsm/IO/ConstantPool.cs +++ b/JavaAsm/IO/ConstantPool.cs @@ -7,97 +7,86 @@ using JavaAsm.Helpers; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.IO -{ - internal class ConstantPool - { +namespace JavaAsm.IO { + internal class ConstantPool { private readonly Dictionary constantPoolMap = new Dictionary(); private readonly List entries = new List(); - public ushort Find(Entry entry) - { - if (constantPoolMap.ContainsKey(entry)) - { - return constantPoolMap[entry]; + public ushort Find(Entry entry) { + if (this.constantPoolMap.ContainsKey(entry)) { + return this.constantPoolMap[entry]; } entry.PutToConstantPool(this); - entries.Add(entry); - var newKey = (ushort) entries.Count; + this.entries.Add(entry); + ushort newKey = (ushort) this.entries.Count; if (entry is LongEntry || entry is DoubleEntry) - entries.Add(new LongDoublePlaceholderEntry()); - if (entries.Count > ushort.MaxValue) + this.entries.Add(new LongDoublePlaceholderEntry()); + if (this.entries.Count > ushort.MaxValue) throw new Exception("Too much entries in constant pool"); - constantPoolMap.Add(entry, newKey); + this.constantPoolMap.Add(entry, newKey); return newKey; } - public T GetEntry(ushort id) where T : Entry - { - return (T) entries[id - 1]; + public T GetEntry(ushort id) where T : Entry { + return (T) this.entries[id - 1]; } - public void Read(Stream stream) - { - var size = Binary.BigEndian.ReadUInt16(stream); - for (var i = 0; i < size - 1; i++) - { - var tag = (EntryTag) stream.ReadByteFully(); - var entry = tag switch - { - EntryTag.Class => (Entry) new ClassEntry(stream), - EntryTag.FieldReference => new FieldReferenceEntry(stream), - EntryTag.MethodReference => new MethodReferenceEntry(stream), - EntryTag.InterfaceMethodReference => new InterfaceMethodReferenceEntry(stream), - EntryTag.String => new StringEntry(stream), - EntryTag.Integer => new IntegerEntry(stream), - EntryTag.Float => new FloatEntry(stream), - EntryTag.Long => new LongEntry(stream), - EntryTag.Double => new DoubleEntry(stream), - EntryTag.NameAndType => new NameAndTypeEntry(stream), - EntryTag.Utf8 => new Utf8Entry(stream), - EntryTag.MethodHandle => new MethodHandleEntry(stream), - EntryTag.MethodType => new MethodTypeEntry(stream), - EntryTag.InvokeDynamic => new InvokeDynamicEntry(stream), - _ => throw new ArgumentOutOfRangeException(nameof(tag)) - }; + public void Read(Stream stream) { + ushort size = Binary.BigEndian.ReadUInt16(stream); + for (int i = 0; i < size - 1; i++) { + EntryTag tag = (EntryTag) stream.ReadByteFully(); + Entry entry; + switch (tag) { + case EntryTag.Class: entry = new ClassEntry(stream); break; + case EntryTag.FieldReference: entry = new FieldReferenceEntry(stream); break; + case EntryTag.MethodReference: entry = new MethodReferenceEntry(stream); break; + case EntryTag.InterfaceMethodReference: entry = new InterfaceMethodReferenceEntry(stream); break; + case EntryTag.String: entry = new StringEntry(stream); break; + case EntryTag.Integer: entry = new IntegerEntry(stream); break; + case EntryTag.Float: entry = new FloatEntry(stream); break; + case EntryTag.Long: entry = new LongEntry(stream); break; + case EntryTag.Double: entry = new DoubleEntry(stream); break; + case EntryTag.NameAndType: entry = new NameAndTypeEntry(stream); break; + case EntryTag.Utf8: entry = new Utf8Entry(stream); break; + case EntryTag.MethodHandle: entry = new MethodHandleEntry(stream); break; + case EntryTag.MethodType: entry = new MethodTypeEntry(stream); break; + case EntryTag.InvokeDynamic: entry = new InvokeDynamicEntry(stream); break; + default: throw new ArgumentOutOfRangeException(nameof(tag)); + } + + Debug.Assert(entry.Tag == tag); - entries.Add(entry); + this.entries.Add(entry); if (!(entry is LongEntry) && !(entry is DoubleEntry)) continue; - entries.Add(new LongDoublePlaceholderEntry()); + this.entries.Add(new LongDoublePlaceholderEntry()); i++; } - foreach (var entry in entries) + foreach (Entry entry in this.entries) entry.ProcessFromConstantPool(this); } - private class LongDoublePlaceholderEntry : Entry - { + private class LongDoublePlaceholderEntry : Entry { public override EntryTag Tag => throw new Exception("You shouldn't access that entry"); - public override void ProcessFromConstantPool(ConstantPool constantPool) - { + public override void ProcessFromConstantPool(ConstantPool constantPool) { } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { } - public override void PutToConstantPool(ConstantPool constantPool) - { + public override void PutToConstantPool(ConstantPool constantPool) { } } - public void Write(Stream stream) - { - if (entries.Count > ushort.MaxValue) - throw new ArgumentOutOfRangeException(nameof(entries.Count), - $"Too many entries: {entries.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(stream, (ushort) (entries.Count + 1)); - foreach (var entry in entries.Where(entry => !(entry is LongDoublePlaceholderEntry))) - { + public void Write(Stream stream) { + if (this.entries.Count > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(this.entries.Count), + $"Too many entries: {this.entries.Count} > {ushort.MaxValue}"); + Binary.BigEndian.Write(stream, (ushort) (this.entries.Count + 1)); + foreach (Entry entry in this.entries.Where(entry => !(entry is LongDoublePlaceholderEntry))) { stream.WriteByte((byte) entry.Tag); entry.Write(stream); } diff --git a/JavaAsm/IO/ConstantPoolEntries/ClassEntry.cs b/JavaAsm/IO/ConstantPoolEntries/ClassEntry.cs index cce924f..ade76bb 100644 --- a/JavaAsm/IO/ConstantPoolEntries/ClassEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/ClassEntry.cs @@ -12,34 +12,34 @@ internal class ClassEntry : Entry public ClassEntry(Utf8Entry name) { - Name = name ?? throw new ArgumentNullException(nameof(name)); + this.Name = name ?? throw new ArgumentNullException(nameof(name)); } public ClassEntry(Stream stream) { - nameIndex = Binary.BigEndian.ReadUInt16(stream); + this.nameIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.Class; public override void ProcessFromConstantPool(ConstantPool constantPool) { - Name = constantPool.GetEntry(nameIndex); + this.Name = constantPool.GetEntry(this.nameIndex); } public override void Write(Stream stream) { - Binary.BigEndian.Write(stream, nameIndex); + Binary.BigEndian.Write(stream, this.nameIndex); } public override void PutToConstantPool(ConstantPool constantPool) { - nameIndex = constantPool.Find(Name); + this.nameIndex = constantPool.Find(this.Name); } private bool Equals(ClassEntry other) { - return Name.Equals(other.Name); + return this.Name.Equals(other.Name); } public override bool Equals(object obj) @@ -52,7 +52,7 @@ public override bool Equals(object obj) [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] public override int GetHashCode() { - return Name.GetHashCode(); + return this.Name.GetHashCode(); } } } \ No newline at end of file diff --git a/JavaAsm/IO/ConstantPoolEntries/DoubleEntry.cs b/JavaAsm/IO/ConstantPoolEntries/DoubleEntry.cs index a655d89..afc3e63 100644 --- a/JavaAsm/IO/ConstantPoolEntries/DoubleEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/DoubleEntry.cs @@ -10,12 +10,12 @@ internal class DoubleEntry : Entry public DoubleEntry(double value) { - Value = value; + this.Value = value; } public DoubleEntry(Stream stream) { - Value = BitConverter.Int64BitsToDouble(Binary.BigEndian.ReadInt64(stream)); + this.Value = BitConverter.Int64BitsToDouble(Binary.BigEndian.ReadInt64(stream)); } public override EntryTag Tag => EntryTag.Double; @@ -24,14 +24,14 @@ public override void ProcessFromConstantPool(ConstantPool constantPool) { } public override void Write(Stream stream) { - Binary.BigEndian.Write(stream, BitConverter.DoubleToInt64Bits(Value)); + Binary.BigEndian.Write(stream, BitConverter.DoubleToInt64Bits(this.Value)); } public override void PutToConstantPool(ConstantPool constantPool) { } private bool Equals(DoubleEntry other) { - return Value.Equals(other.Value); + return this.Value.Equals(other.Value); } public override bool Equals(object obj) @@ -43,7 +43,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return Value.GetHashCode(); + return this.Value.GetHashCode(); } } } \ No newline at end of file diff --git a/JavaAsm/IO/ConstantPoolEntries/FloatEntry.cs b/JavaAsm/IO/ConstantPoolEntries/FloatEntry.cs index 1119c12..6e12c3d 100644 --- a/JavaAsm/IO/ConstantPoolEntries/FloatEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/FloatEntry.cs @@ -2,48 +2,48 @@ using System.IO; using BinaryEncoding; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class FloatEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class FloatEntry : Entry { public float Value { get; } - public FloatEntry(float value) - { - Value = value; + public FloatEntry(float value) { + this.Value = value; } - public FloatEntry(Stream stream) - { - Value = BitConverter.Int32BitsToSingle(Binary.BigEndian.ReadInt32(stream)); + public FloatEntry(Stream stream) { + unsafe { + int value = Binary.BigEndian.ReadInt32(stream); + this.Value = *(float*) &value; + } } public override EntryTag Tag => EntryTag.Float; public override void ProcessFromConstantPool(ConstantPool constantPool) { } - public override void Write(Stream stream) - { - Binary.BigEndian.Write(stream, BitConverter.SingleToInt32Bits(Value)); + public override void Write(Stream stream) { + unsafe { + float value = this.Value; + Binary.BigEndian.Write(stream, *(int*) &value); + } } public override void PutToConstantPool(ConstantPool constantPool) { } - private bool Equals(FloatEntry other) - { - return Value.Equals(other.Value); + private bool Equals(FloatEntry other) { + return this.Value.Equals(other.Value); } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((FloatEntry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((FloatEntry) obj); } - public override int GetHashCode() - { - return Value.GetHashCode(); + public override int GetHashCode() { + return this.Value.GetHashCode(); } } } \ No newline at end of file diff --git a/JavaAsm/IO/ConstantPoolEntries/IntegerEntry.cs b/JavaAsm/IO/ConstantPoolEntries/IntegerEntry.cs index 0be6fba..5756010 100644 --- a/JavaAsm/IO/ConstantPoolEntries/IntegerEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/IntegerEntry.cs @@ -9,12 +9,12 @@ internal class IntegerEntry : Entry public IntegerEntry(int value) { - Value = value; + this.Value = value; } public IntegerEntry(Stream stream) { - Value = Binary.BigEndian.ReadInt32(stream); + this.Value = Binary.BigEndian.ReadInt32(stream); } public override EntryTag Tag => EntryTag.Integer; @@ -23,14 +23,14 @@ public override void ProcessFromConstantPool(ConstantPool constantPool) { } public override void Write(Stream stream) { - Binary.BigEndian.Write(stream, Value); + Binary.BigEndian.Write(stream, this.Value); } public override void PutToConstantPool(ConstantPool constantPool) { } private bool Equals(IntegerEntry other) { - return Value == other.Value; + return this.Value == other.Value; } public override bool Equals(object obj) @@ -42,7 +42,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return Value; + return this.Value; } } } \ No newline at end of file diff --git a/JavaAsm/IO/ConstantPoolEntries/InvokeDynamicEntry.cs b/JavaAsm/IO/ConstantPoolEntries/InvokeDynamicEntry.cs index dfa4908..84c6976 100644 --- a/JavaAsm/IO/ConstantPoolEntries/InvokeDynamicEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/InvokeDynamicEntry.cs @@ -14,37 +14,37 @@ internal class InvokeDynamicEntry : Entry public InvokeDynamicEntry(ushort bootstrapMethodAttributeIndex, NameAndTypeEntry nameAndType) { - BootstrapMethodAttributeIndex = bootstrapMethodAttributeIndex; - NameAndType = nameAndType ?? throw new ArgumentNullException(nameof(nameAndType)); + this.BootstrapMethodAttributeIndex = bootstrapMethodAttributeIndex; + this.NameAndType = nameAndType ?? throw new ArgumentNullException(nameof(nameAndType)); } public InvokeDynamicEntry(Stream stream) { - BootstrapMethodAttributeIndex = Binary.BigEndian.ReadUInt16(stream); - nameAndTypeIndex = Binary.BigEndian.ReadUInt16(stream); + this.BootstrapMethodAttributeIndex = Binary.BigEndian.ReadUInt16(stream); + this.nameAndTypeIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.InvokeDynamic; public override void ProcessFromConstantPool(ConstantPool constantPool) { - NameAndType = constantPool.GetEntry(nameAndTypeIndex); + this.NameAndType = constantPool.GetEntry(this.nameAndTypeIndex); } public override void Write(Stream stream) { - Binary.BigEndian.Write(stream, BootstrapMethodAttributeIndex); - Binary.BigEndian.Write(stream, nameAndTypeIndex); + Binary.BigEndian.Write(stream, this.BootstrapMethodAttributeIndex); + Binary.BigEndian.Write(stream, this.nameAndTypeIndex); } public override void PutToConstantPool(ConstantPool constantPool) { - nameAndTypeIndex = constantPool.Find(NameAndType); + this.nameAndTypeIndex = constantPool.Find(this.NameAndType); } private bool Equals(InvokeDynamicEntry other) { - return BootstrapMethodAttributeIndex == other.BootstrapMethodAttributeIndex && Equals(NameAndType, other.NameAndType); + return this.BootstrapMethodAttributeIndex == other.BootstrapMethodAttributeIndex && Equals(this.NameAndType, other.NameAndType); } public override bool Equals(object obj) @@ -59,7 +59,7 @@ public override int GetHashCode() { unchecked { - return (BootstrapMethodAttributeIndex.GetHashCode() * 397) ^ (NameAndType != null ? NameAndType.GetHashCode() : 0); + return (this.BootstrapMethodAttributeIndex.GetHashCode() * 397) ^ (this.NameAndType != null ? this.NameAndType.GetHashCode() : 0); } } } diff --git a/JavaAsm/IO/ConstantPoolEntries/LongEntry.cs b/JavaAsm/IO/ConstantPoolEntries/LongEntry.cs index d980e7f..2c9dd51 100644 --- a/JavaAsm/IO/ConstantPoolEntries/LongEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/LongEntry.cs @@ -9,12 +9,12 @@ internal class LongEntry : Entry public LongEntry(long value) { - Value = value; + this.Value = value; } public LongEntry(Stream stream) { - Value = Binary.BigEndian.ReadInt64(stream); + this.Value = Binary.BigEndian.ReadInt64(stream); } public override EntryTag Tag => EntryTag.Long; @@ -23,14 +23,14 @@ public override void ProcessFromConstantPool(ConstantPool constantPool) { } public override void Write(Stream stream) { - Binary.BigEndian.Write(stream, Value); + Binary.BigEndian.Write(stream, this.Value); } public override void PutToConstantPool(ConstantPool constantPool) { } private bool Equals(LongEntry other) { - return Value == other.Value; + return this.Value == other.Value; } public override bool Equals(object obj) @@ -42,7 +42,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return Value.GetHashCode(); + return this.Value.GetHashCode(); } } } \ No newline at end of file diff --git a/JavaAsm/IO/ConstantPoolEntries/MethodHandleEntry.cs b/JavaAsm/IO/ConstantPoolEntries/MethodHandleEntry.cs index 0ebeffd..deaa0d4 100644 --- a/JavaAsm/IO/ConstantPoolEntries/MethodHandleEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/MethodHandleEntry.cs @@ -16,65 +16,65 @@ internal class MethodHandleEntry : Entry public MethodHandleEntry(ReferenceKindType referenceKind, ReferenceEntry reference) { - ReferenceKind = referenceKind; - Reference = reference ?? throw new ArgumentNullException(nameof(reference)); + this.ReferenceKind = referenceKind; + this.Reference = reference ?? throw new ArgumentNullException(nameof(reference)); } public MethodHandleEntry(Stream stream) { - ReferenceKind = (ReferenceKindType) stream.ReadByteFully(); - referenceIndex = Binary.BigEndian.ReadUInt16(stream); + this.ReferenceKind = (ReferenceKindType) stream.ReadByteFully(); + this.referenceIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.MethodHandle; public override void ProcessFromConstantPool(ConstantPool constantPool) { - switch (ReferenceKind) + switch (this.ReferenceKind) { case ReferenceKindType.GetField: case ReferenceKindType.GetStatic: case ReferenceKindType.PutField: case ReferenceKindType.PutStatic: - Reference = constantPool.GetEntry(referenceIndex); + this.Reference = constantPool.GetEntry(this.referenceIndex); break; case ReferenceKindType.InvokeVirtual: case ReferenceKindType.NewInvokeSpecial: - Reference = constantPool.GetEntry(referenceIndex); + this.Reference = constantPool.GetEntry(this.referenceIndex); break; case ReferenceKindType.InvokeStatic: case ReferenceKindType.InvokeSpecial: try { - Reference = constantPool.GetEntry(referenceIndex); + this.Reference = constantPool.GetEntry(this.referenceIndex); } catch (InvalidCastException) { - Reference = constantPool.GetEntry(referenceIndex); + this.Reference = constantPool.GetEntry(this.referenceIndex); } break; case ReferenceKindType.InvokeReference: - Reference = constantPool.GetEntry(referenceIndex); + this.Reference = constantPool.GetEntry(this.referenceIndex); break; default: - throw new ArgumentOutOfRangeException(nameof(ReferenceKind)); + throw new ArgumentOutOfRangeException(nameof(this.ReferenceKind)); } } public override void Write(Stream stream) { - stream.WriteByte((byte)ReferenceKind); - Binary.BigEndian.Write(stream, referenceIndex); + stream.WriteByte((byte) this.ReferenceKind); + Binary.BigEndian.Write(stream, this.referenceIndex); } public override void PutToConstantPool(ConstantPool constantPool) { - referenceIndex = constantPool.Find(Reference); + this.referenceIndex = constantPool.Find(this.Reference); } private bool Equals(MethodHandleEntry other) { - return ReferenceKind == other.ReferenceKind && Equals(Reference, other.Reference); + return this.ReferenceKind == other.ReferenceKind && Equals(this.Reference, other.Reference); } public override bool Equals(object obj) @@ -89,7 +89,7 @@ public override int GetHashCode() { unchecked { - return ((int)ReferenceKind * 397) ^ (Reference != null ? Reference.GetHashCode() : 0); + return ((int) this.ReferenceKind * 397) ^ (this.Reference != null ? this.Reference.GetHashCode() : 0); } } } diff --git a/JavaAsm/IO/ConstantPoolEntries/MethodTypeEntry.cs b/JavaAsm/IO/ConstantPoolEntries/MethodTypeEntry.cs index 9b85057..63caaf0 100644 --- a/JavaAsm/IO/ConstantPoolEntries/MethodTypeEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/MethodTypeEntry.cs @@ -12,34 +12,34 @@ internal class MethodTypeEntry : Entry public MethodTypeEntry(Utf8Entry descriptor) { - Descriptor = descriptor ?? throw new ArgumentNullException(nameof(descriptor)); + this.Descriptor = descriptor ?? throw new ArgumentNullException(nameof(descriptor)); } public MethodTypeEntry(Stream stream) { - descriptorIndex = Binary.BigEndian.ReadUInt16(stream); + this.descriptorIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.MethodType; public override void ProcessFromConstantPool(ConstantPool constantPool) { - Descriptor = constantPool.GetEntry(descriptorIndex); + this.Descriptor = constantPool.GetEntry(this.descriptorIndex); } public override void Write(Stream stream) { - Binary.BigEndian.Write(stream, descriptorIndex); + Binary.BigEndian.Write(stream, this.descriptorIndex); } public override void PutToConstantPool(ConstantPool constantPool) { - descriptorIndex = constantPool.Find(Descriptor); + this.descriptorIndex = constantPool.Find(this.Descriptor); } private bool Equals(MethodTypeEntry other) { - return Equals(Descriptor, other.Descriptor); + return Equals(this.Descriptor, other.Descriptor); } public override bool Equals(object obj) @@ -52,7 +52,7 @@ public override bool Equals(object obj) [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] public override int GetHashCode() { - return Descriptor != null ? Descriptor.GetHashCode() : 0; + return this.Descriptor != null ? this.Descriptor.GetHashCode() : 0; } } } \ No newline at end of file diff --git a/JavaAsm/IO/ConstantPoolEntries/NameAndTypeEntry.cs b/JavaAsm/IO/ConstantPoolEntries/NameAndTypeEntry.cs index 64e52c0..df1cf20 100644 --- a/JavaAsm/IO/ConstantPoolEntries/NameAndTypeEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/NameAndTypeEntry.cs @@ -15,39 +15,39 @@ internal class NameAndTypeEntry : Entry public NameAndTypeEntry(Utf8Entry name, Utf8Entry descriptor) { - Name = name ?? throw new ArgumentNullException(nameof(name)); - Descriptor = descriptor ?? throw new ArgumentNullException(nameof(descriptor)); + this.Name = name ?? throw new ArgumentNullException(nameof(name)); + this.Descriptor = descriptor ?? throw new ArgumentNullException(nameof(descriptor)); } public NameAndTypeEntry(Stream stream) { - nameIndex = Binary.BigEndian.ReadUInt16(stream); - descriptorIndex = Binary.BigEndian.ReadUInt16(stream); + this.nameIndex = Binary.BigEndian.ReadUInt16(stream); + this.descriptorIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.NameAndType; public override void ProcessFromConstantPool(ConstantPool constantPool) { - Name = constantPool.GetEntry(nameIndex); - Descriptor = constantPool.GetEntry(descriptorIndex); + this.Name = constantPool.GetEntry(this.nameIndex); + this.Descriptor = constantPool.GetEntry(this.descriptorIndex); } public override void Write(Stream stream) { - Binary.BigEndian.Write(stream, nameIndex); - Binary.BigEndian.Write(stream, descriptorIndex); + Binary.BigEndian.Write(stream, this.nameIndex); + Binary.BigEndian.Write(stream, this.descriptorIndex); } public override void PutToConstantPool(ConstantPool constantPool) { - nameIndex = constantPool.Find(Name); - descriptorIndex = constantPool.Find(Descriptor); + this.nameIndex = constantPool.Find(this.Name); + this.descriptorIndex = constantPool.Find(this.Descriptor); } private bool Equals(NameAndTypeEntry other) { - return Name.Equals(other.Name) && Descriptor.Equals(other.Descriptor); + return this.Name.Equals(other.Name) && this.Descriptor.Equals(other.Descriptor); } public override bool Equals(object obj) @@ -62,7 +62,7 @@ public override int GetHashCode() { unchecked { - return (Name.GetHashCode() * 397) ^ Descriptor.GetHashCode(); + return (this.Name.GetHashCode() * 397) ^ this.Descriptor.GetHashCode(); } } } diff --git a/JavaAsm/IO/ConstantPoolEntries/ReferenceEntry.cs b/JavaAsm/IO/ConstantPoolEntries/ReferenceEntry.cs index 6978759..2ea7cd8 100644 --- a/JavaAsm/IO/ConstantPoolEntries/ReferenceEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/ReferenceEntry.cs @@ -15,37 +15,37 @@ internal abstract class ReferenceEntry : Entry protected ReferenceEntry(ClassEntry @class, NameAndTypeEntry nameAndType) { - Class = @class ?? throw new ArgumentNullException(nameof(@class)); - NameAndType = nameAndType ?? throw new ArgumentNullException(nameof(nameAndType)); + this.Class = @class ?? throw new ArgumentNullException(nameof(@class)); + this.NameAndType = nameAndType ?? throw new ArgumentNullException(nameof(nameAndType)); } protected ReferenceEntry(Stream stream) { - classIndex = Binary.BigEndian.ReadUInt16(stream); - nameAndTypeIndex = Binary.BigEndian.ReadUInt16(stream); + this.classIndex = Binary.BigEndian.ReadUInt16(stream); + this.nameAndTypeIndex = Binary.BigEndian.ReadUInt16(stream); } public override void ProcessFromConstantPool(ConstantPool constantPool) { - Class = constantPool.GetEntry(classIndex); - NameAndType = constantPool.GetEntry(nameAndTypeIndex); + this.Class = constantPool.GetEntry(this.classIndex); + this.NameAndType = constantPool.GetEntry(this.nameAndTypeIndex); } public override void Write(Stream stream) { - Binary.BigEndian.Write(stream, classIndex); - Binary.BigEndian.Write(stream, nameAndTypeIndex); + Binary.BigEndian.Write(stream, this.classIndex); + Binary.BigEndian.Write(stream, this.nameAndTypeIndex); } public override void PutToConstantPool(ConstantPool constantPool) { - classIndex = constantPool.Find(Class); - nameAndTypeIndex = constantPool.Find(NameAndType); + this.classIndex = constantPool.Find(this.Class); + this.nameAndTypeIndex = constantPool.Find(this.NameAndType); } private bool Equals(ReferenceEntry other) { - return Class.Equals(other.Class) && NameAndType.Equals(other.NameAndType); + return this.Class.Equals(other.Class) && this.NameAndType.Equals(other.NameAndType); } public override bool Equals(object obj) @@ -60,7 +60,7 @@ public override int GetHashCode() { unchecked { - return (Class.GetHashCode() * 397) ^ NameAndType.GetHashCode(); + return (this.Class.GetHashCode() * 397) ^ this.NameAndType.GetHashCode(); } } } diff --git a/JavaAsm/IO/ConstantPoolEntries/StringEntry.cs b/JavaAsm/IO/ConstantPoolEntries/StringEntry.cs index 19a3441..27512d2 100644 --- a/JavaAsm/IO/ConstantPoolEntries/StringEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/StringEntry.cs @@ -12,34 +12,34 @@ internal class StringEntry : Entry public StringEntry(Utf8Entry @string) { - Value = @string ?? throw new ArgumentNullException(nameof(@string)); + this.Value = @string ?? throw new ArgumentNullException(nameof(@string)); } public StringEntry(Stream stream) { - nameIndex = Binary.BigEndian.ReadUInt16(stream); + this.nameIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.String; public override void ProcessFromConstantPool(ConstantPool constantPool) { - Value = constantPool.GetEntry(nameIndex); + this.Value = constantPool.GetEntry(this.nameIndex); } public override void Write(Stream stream) { - Binary.BigEndian.Write(stream, nameIndex); + Binary.BigEndian.Write(stream, this.nameIndex); } public override void PutToConstantPool(ConstantPool constantPool) { - nameIndex = constantPool.Find(Value); + this.nameIndex = constantPool.Find(this.Value); } private bool Equals(StringEntry other) { - return Value.Equals(other.Value); + return this.Value.Equals(other.Value); } public override bool Equals(object obj) @@ -52,7 +52,7 @@ public override bool Equals(object obj) [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] public override int GetHashCode() { - return Value.GetHashCode(); + return this.Value.GetHashCode(); } } } \ No newline at end of file diff --git a/JavaAsm/IO/ConstantPoolEntries/Utf8Entry.cs b/JavaAsm/IO/ConstantPoolEntries/Utf8Entry.cs index b2601ff..653e2ae 100644 --- a/JavaAsm/IO/ConstantPoolEntries/Utf8Entry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/Utf8Entry.cs @@ -11,14 +11,14 @@ internal class Utf8Entry : Entry public Utf8Entry(string @string) { - String = @string ?? throw new ArgumentNullException(nameof(@string)); + this.String = @string ?? throw new ArgumentNullException(nameof(@string)); } public Utf8Entry(Stream stream) { - var data = new byte[Binary.BigEndian.ReadUInt16(stream)]; - stream.Read(data); - String = ModifiedUtf8Helper.Decode(data); + byte[] data = new byte[Binary.BigEndian.ReadUInt16(stream)]; + stream.Read(data, 0, data.Length); + this.String = ModifiedUtf8Helper.Decode(data); } public override EntryTag Tag => EntryTag.Utf8; @@ -27,15 +27,15 @@ public override void ProcessFromConstantPool(ConstantPool constantPool) { } public override void Write(Stream stream) { - Binary.BigEndian.Write(stream, ModifiedUtf8Helper.GetBytesCount(String)); - stream.Write(ModifiedUtf8Helper.Encode(String)); + Binary.BigEndian.Write(stream, ModifiedUtf8Helper.GetBytesCount(this.String)); + stream.Write(ModifiedUtf8Helper.Encode(this.String)); } public override void PutToConstantPool(ConstantPool constantPool) { } private bool Equals(Utf8Entry other) { - return String == other.String; + return this.String == other.String; } public override bool Equals(object obj) @@ -47,7 +47,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return String.GetHashCode(); + return this.String.GetHashCode(); } } } \ No newline at end of file diff --git a/JavaAsm/Instructions/InstructionList.cs b/JavaAsm/Instructions/InstructionList.cs index 2433564..255d20a 100644 --- a/JavaAsm/Instructions/InstructionList.cs +++ b/JavaAsm/Instructions/InstructionList.cs @@ -10,32 +10,32 @@ private class InstructionListEnumerator : IEnumerator { public InstructionListEnumerator(Instruction start) { - Start = start; + this.Start = start; } public bool MoveNext() { - if (Start != null && Current == null) + if (this.Start != null && this.Current == null) { - Current = Start; + this.Current = this.Start; return true; } - if (Current?.Next == null) + if (this.Current?.Next == null) return false; - Current = Current.Next; + this.Current = this.Current.Next; return true; } public void Reset() { - Current = null; + this.Current = null; } public Instruction Current { get; private set; } private Instruction Start { get; } - object IEnumerator.Current => Current; + object IEnumerator.Current => this.Current; public void Dispose() { } } @@ -50,13 +50,13 @@ public void Add(Instruction instruction) { instruction.OwnerList = this; instruction.Next = null; - if (First == null) - First = instruction; - instruction.Previous = Last; - Last = instruction; + if (this.First == null) + this.First = instruction; + instruction.Previous = this.Last; + this.Last = instruction; if (instruction.Previous != null) instruction.Previous.Next = instruction; - Count++; + this.Count++; } public void InsertBefore(Instruction instruction, Instruction toInsert) @@ -71,9 +71,9 @@ public void InsertBefore(Instruction instruction, Instruction toInsert) toInsert.Previous.Next = toInsert; toInsert.Next.Previous = toInsert; - if (ReferenceEquals(instruction, First)) - First = toInsert; - Count++; + if (ReferenceEquals(instruction, this.First)) + this.First = toInsert; + this.Count++; } public void InsertAfter(Instruction instruction, Instruction toInsert) @@ -88,9 +88,9 @@ public void InsertAfter(Instruction instruction, Instruction toInsert) toInsert.Next.Previous = toInsert; toInsert.Previous.Next = toInsert; - if (ReferenceEquals(instruction, Last)) - Last = toInsert; - Count++; + if (ReferenceEquals(instruction, this.Last)) + this.Last = toInsert; + this.Count++; } public void Remove(Instruction instruction) @@ -102,16 +102,16 @@ public void Remove(Instruction instruction) instruction.Next.Previous = instruction.Previous; if (instruction.Previous != null) instruction.Previous.Next = instruction.Next; - if (ReferenceEquals(instruction, First)) - First = instruction.Next; - if (ReferenceEquals(instruction, Last)) - Last = instruction.Previous; - Count--; + if (ReferenceEquals(instruction, this.First)) + this.First = instruction.Next; + if (ReferenceEquals(instruction, this.Last)) + this.Last = instruction.Previous; + this.Count--; } public IEnumerator GetEnumerator() { - return new InstructionListEnumerator(First); + return new InstructionListEnumerator(this.First); } IEnumerator IEnumerable.GetEnumerator() diff --git a/JavaAsm/Instructions/InstructionListConverter.cs b/JavaAsm/Instructions/InstructionListConverter.cs index 82a43cc..709f8fd 100644 --- a/JavaAsm/Instructions/InstructionListConverter.cs +++ b/JavaAsm/Instructions/InstructionListConverter.cs @@ -15,7 +15,7 @@ internal static class InstructionListConverter { private static AttributeNode GetAttribute(ICollection attributes, string name) { - var attribute = attributes.FirstOrDefault(a => a.Name == name); + AttributeNode attribute = attributes.FirstOrDefault(a => a.Name == name); if (attribute != null) attributes.Remove(attribute); return attribute; @@ -30,22 +30,20 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade if (codeAttribute.Code.Length == 0) return; - var bootstrapMethodsAttribute = readerState.ClassNode.Attributes + BootstrapMethodsAttribute bootstrapMethodsAttribute = readerState.ClassNode.Attributes .FirstOrDefault(x => x.Name == PredefinedAttributeNames.BootstrapMethods)?.ParsedAttribute as BootstrapMethodsAttribute; - var instructions = new Dictionary(); - var labels = new Dictionary(); + Dictionary instructions = new Dictionary(); + Dictionary labels = new Dictionary(); - var wideFlag = false; + bool wideFlag = false; - using var codeStream = new MemoryStream(codeAttribute.Code); - while (codeStream.Position != codeStream.Length) - { - var currentPosition = codeStream.Position; + MemoryStream codeStream = new MemoryStream(codeAttribute.Code); + while (codeStream.Position != codeStream.Length) { + long currentPosition = codeStream.Position; - var opcode = (Opcode) codeStream.ReadByteFully(); - switch (opcode) - { + Opcode opcode = (Opcode) codeStream.ReadByteFully(); + switch (opcode) { case Opcode.NOP: case Opcode.ACONST_NULL: case Opcode.ICONST_M1: @@ -173,72 +171,61 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.GOTO: case Opcode.JSR: case Opcode.IFNULL: - case Opcode.IFNONNULL: - { - instructions.Add(currentPosition, new JumpInstruction(opcode) - { - Target = labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt16(codeStream), new Label()) - }); - } + case Opcode.IFNONNULL: { + instructions.Add(currentPosition, new JumpInstruction(opcode) { + Target = labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt16(codeStream), new Label()) + }); + } break; case Opcode.JSR_W: - case Opcode.GOTO_W: - { - instructions.Add(currentPosition, new JumpInstruction(opcode == Opcode.JSR_W ? Opcode.JSR : Opcode.GOTO) - { - Target = labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt32(codeStream), new Label()) - }); - } + case Opcode.GOTO_W: { + instructions.Add(currentPosition, new JumpInstruction(opcode == Opcode.JSR_W ? Opcode.JSR : Opcode.GOTO) { + Target = labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt32(codeStream), new Label()) + }); + } break; - case Opcode.LOOKUPSWITCH: - { - while (codeStream.Position % 4 != 0) - codeStream.ReadByteFully(); - var lookupSwitchInstruction = new LookupSwitchInstruction - { - Default = labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt32(codeStream), new Label()) - }; - var nPairs = Binary.BigEndian.ReadInt32(codeStream); - lookupSwitchInstruction.MatchLabels.Capacity = nPairs; - for (var i = 0; i < nPairs; i++) - { - lookupSwitchInstruction.MatchLabels.Add(new KeyValuePair( - Binary.BigEndian.ReadInt32(codeStream), - labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt32(codeStream), new Label()))); - } - - instructions.Add(currentPosition, lookupSwitchInstruction); + case Opcode.LOOKUPSWITCH: { + while (codeStream.Position % 4 != 0) + codeStream.ReadByteFully(); + LookupSwitchInstruction lookupSwitchInstruction = new LookupSwitchInstruction { + Default = labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt32(codeStream), new Label()) + }; + int nPairs = Binary.BigEndian.ReadInt32(codeStream); + lookupSwitchInstruction.MatchLabels.Capacity = nPairs; + for (int i = 0; i < nPairs; i++) { + lookupSwitchInstruction.MatchLabels.Add(new KeyValuePair( + Binary.BigEndian.ReadInt32(codeStream), + labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt32(codeStream), new Label()))); } - break; - case Opcode.TABLESWITCH: - { - while (codeStream.Position % 4 != 0) - codeStream.ReadByteFully(); - var tableSwitchInstruction = new TableSwitchInstruction - { - Default = labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt32(codeStream), new Label()), - LowValue = Binary.BigEndian.ReadInt32(codeStream), - HighValue = Binary.BigEndian.ReadInt32(codeStream) - }; - for (var i = tableSwitchInstruction.LowValue; i <= tableSwitchInstruction.HighValue; i++) - { - tableSwitchInstruction.Labels.Add( - labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt32(codeStream), new Label())); - } + instructions.Add(currentPosition, lookupSwitchInstruction); + } + break; - instructions.Add(currentPosition, tableSwitchInstruction); + case Opcode.TABLESWITCH: { + while (codeStream.Position % 4 != 0) + codeStream.ReadByteFully(); + TableSwitchInstruction tableSwitchInstruction = new TableSwitchInstruction { + Default = labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt32(codeStream), new Label()), + LowValue = Binary.BigEndian.ReadInt32(codeStream), + HighValue = Binary.BigEndian.ReadInt32(codeStream) + }; + for (int i = tableSwitchInstruction.LowValue; i <= tableSwitchInstruction.HighValue; i++) { + tableSwitchInstruction.Labels.Add( + labels.GetOrAdd(currentPosition + Binary.BigEndian.ReadInt32(codeStream), new Label())); } + + instructions.Add(currentPosition, tableSwitchInstruction); + } break; case Opcode.INVOKEDYNAMIC: - var callSiteSpecifier = readerState.ConstantPool.GetEntry( - Binary.BigEndian.ReadUInt16(codeStream)); + InvokeDynamicEntry callSiteSpecifier = readerState.ConstantPool.GetEntry( + Binary.BigEndian.ReadUInt16(codeStream)); if (Binary.BigEndian.ReadUInt16(codeStream) != 0) throw new ArgumentException("INVOKEDYNAMIC 3rd and 4th bytes != 0"); - instructions.Add(currentPosition, new InvokeDynamicInstruction - { + instructions.Add(currentPosition, new InvokeDynamicInstruction { Name = callSiteSpecifier.NameAndType.Name.String, Descriptor = MethodDescriptor.Parse(callSiteSpecifier.NameAndType.Descriptor.String), BootstrapMethod = bootstrapMethodsAttribute.BootstrapMethods[callSiteSpecifier.BootstrapMethodAttributeIndex].BootstrapMethodReference, @@ -247,17 +234,14 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade break; case Opcode.NEWARRAY: - instructions.Add(currentPosition, new NewArrayInstruction - { + instructions.Add(currentPosition, new NewArrayInstruction { ArrayType = (NewArrayTypeCode) codeStream.ReadByteFully() }); break; case Opcode.MULTIANEWARRAY: - instructions.Add(currentPosition, new MultiANewArrayInstruction - { - Type = new ClassName(readerState.ConstantPool - .GetEntry(Binary.BigEndian.ReadUInt16(codeStream)).Name.String), + instructions.Add(currentPosition, new MultiANewArrayInstruction { + Type = new ClassName(readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(codeStream)).Name.String), Dimensions = codeStream.ReadByteFully() }); break; @@ -266,41 +250,35 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.INSTANCEOF: case Opcode.ANEWARRAY: case Opcode.NEW: - instructions.Add(currentPosition, new TypeInstruction(opcode) - { + instructions.Add(currentPosition, new TypeInstruction(opcode) { Type = new ClassName(readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(codeStream)).Name.String) }); break; case Opcode.IINC: - if (wideFlag) - { - instructions.Add(currentPosition - 1, new IncrementInstruction - { + if (wideFlag) { + instructions.Add(currentPosition - 1, new IncrementInstruction { VariableIndex = Binary.BigEndian.ReadUInt16(codeStream), Value = Binary.BigEndian.ReadInt16(codeStream) }); wideFlag = false; - } - else - { - instructions.Add(currentPosition, new IncrementInstruction - { + } + else { + instructions.Add(currentPosition, new IncrementInstruction { VariableIndex = codeStream.ReadByteFully(), Value = codeStream.ReadByteFully() }); } + break; case Opcode.BIPUSH: - instructions.Add(currentPosition, new IntegerPushInstruction(opcode) - { + instructions.Add(currentPosition, new IntegerPushInstruction(opcode) { Value = codeStream.ReadByteFully() }); break; case Opcode.SIPUSH: - instructions.Add(currentPosition, new IntegerPushInstruction(opcode) - { + instructions.Add(currentPosition, new IntegerPushInstruction(opcode) { Value = Binary.BigEndian.ReadUInt16(codeStream) }); break; @@ -317,19 +295,16 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.LSTORE: case Opcode.RET: ushort variableIndex; - if (wideFlag) - { + if (wideFlag) { variableIndex = Binary.BigEndian.ReadUInt16(codeStream); currentPosition--; wideFlag = false; - } - else - { + } + else { variableIndex = codeStream.ReadByteFully(); } - instructions.Add(currentPosition, new VariableInstruction(opcode) - { + instructions.Add(currentPosition, new VariableInstruction(opcode) { VariableIndex = variableIndex }); break; @@ -337,8 +312,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.ALOAD_1: case Opcode.ALOAD_2: case Opcode.ALOAD_3: - instructions.Add(currentPosition, new VariableInstruction(Opcode.ALOAD) - { + instructions.Add(currentPosition, new VariableInstruction(Opcode.ALOAD) { VariableIndex = opcode - Opcode.ALOAD_0 }); break; @@ -346,8 +320,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.ASTORE_1: case Opcode.ASTORE_2: case Opcode.ASTORE_3: - instructions.Add(currentPosition, new VariableInstruction(Opcode.ASTORE) - { + instructions.Add(currentPosition, new VariableInstruction(Opcode.ASTORE) { VariableIndex = opcode - Opcode.ASTORE_0 }); break; @@ -355,8 +328,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.DLOAD_1: case Opcode.DLOAD_2: case Opcode.DLOAD_3: - instructions.Add(currentPosition, new VariableInstruction(Opcode.DLOAD) - { + instructions.Add(currentPosition, new VariableInstruction(Opcode.DLOAD) { VariableIndex = opcode - Opcode.DLOAD_0 }); break; @@ -364,8 +336,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.DSTORE_1: case Opcode.DSTORE_2: case Opcode.DSTORE_3: - instructions.Add(currentPosition, new VariableInstruction(Opcode.DSTORE) - { + instructions.Add(currentPosition, new VariableInstruction(Opcode.DSTORE) { VariableIndex = opcode - Opcode.DSTORE_0 }); break; @@ -373,8 +344,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.FLOAD_1: case Opcode.FLOAD_2: case Opcode.FLOAD_3: - instructions.Add(currentPosition, new VariableInstruction(Opcode.FLOAD) - { + instructions.Add(currentPosition, new VariableInstruction(Opcode.FLOAD) { VariableIndex = opcode - Opcode.FLOAD_0 }); break; @@ -382,8 +352,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.FSTORE_1: case Opcode.FSTORE_2: case Opcode.FSTORE_3: - instructions.Add(currentPosition, new VariableInstruction(Opcode.FSTORE) - { + instructions.Add(currentPosition, new VariableInstruction(Opcode.FSTORE) { VariableIndex = opcode - Opcode.FSTORE_0 }); break; @@ -391,8 +360,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.ILOAD_1: case Opcode.ILOAD_2: case Opcode.ILOAD_3: - instructions.Add(currentPosition, new VariableInstruction(Opcode.ILOAD) - { + instructions.Add(currentPosition, new VariableInstruction(Opcode.ILOAD) { VariableIndex = opcode - Opcode.ILOAD_0 }); break; @@ -400,8 +368,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.ISTORE_1: case Opcode.ISTORE_2: case Opcode.ISTORE_3: - instructions.Add(currentPosition, new VariableInstruction(Opcode.ISTORE) - { + instructions.Add(currentPosition, new VariableInstruction(Opcode.ISTORE) { VariableIndex = opcode - Opcode.ISTORE_0 }); break; @@ -409,8 +376,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.LLOAD_1: case Opcode.LLOAD_2: case Opcode.LLOAD_3: - instructions.Add(currentPosition, new VariableInstruction(Opcode.LLOAD) - { + instructions.Add(currentPosition, new VariableInstruction(Opcode.LLOAD) { VariableIndex = opcode - Opcode.LLOAD_0 }); break; @@ -418,8 +384,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.LSTORE_1: case Opcode.LSTORE_2: case Opcode.LSTORE_3: - instructions.Add(currentPosition, new VariableInstruction(Opcode.LSTORE) - { + instructions.Add(currentPosition, new VariableInstruction(Opcode.LSTORE) { VariableIndex = opcode - Opcode.LSTORE_0 }); break; @@ -427,117 +392,93 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade case Opcode.INVOKEINTERFACE: case Opcode.INVOKESPECIAL: case Opcode.INVOKESTATIC: - case Opcode.INVOKEVIRTUAL: - { - MethodReferenceEntry methodReferenceEntry; - if (opcode == Opcode.INVOKEINTERFACE) - { - methodReferenceEntry = readerState.ConstantPool.GetEntry( - Binary.BigEndian.ReadUInt16(codeStream)); - var sizeOfArguments = codeStream.ReadByteFully(); - var requiredSizeOfArguments = - MethodDescriptor.Parse(methodReferenceEntry.NameAndType.Descriptor.String).ArgumentTypes.Sum(x => x.SizeOnStack) + 1; - if (sizeOfArguments != requiredSizeOfArguments) - throw new ArgumentOutOfRangeException(nameof(sizeOfArguments), $"Required size does not equal to provided: {requiredSizeOfArguments} > {sizeOfArguments}"); - if (codeStream.ReadByteFully() != 0) - throw new ArgumentException("INVOKEINTERFACE 4th byte is not 0"); - } - else - { - methodReferenceEntry = readerState.ConstantPool.GetEntry( - Binary.BigEndian.ReadUInt16(codeStream)); - } - - instructions.Add(currentPosition, new MethodInstruction(opcode) - { - Owner = new ClassName(methodReferenceEntry.Class.Name.String), - Descriptor = MethodDescriptor.Parse(methodReferenceEntry.NameAndType.Descriptor.String), - Name = methodReferenceEntry.NameAndType.Name.String - }); + case Opcode.INVOKEVIRTUAL: { + MethodReferenceEntry methodReferenceEntry; + if (opcode == Opcode.INVOKEINTERFACE) { + methodReferenceEntry = readerState.ConstantPool.GetEntry( + Binary.BigEndian.ReadUInt16(codeStream)); + byte sizeOfArguments = codeStream.ReadByteFully(); + int requiredSizeOfArguments = + MethodDescriptor.Parse(methodReferenceEntry.NameAndType.Descriptor.String).ArgumentTypes.Sum(x => x.SizeOnStack) + 1; + if (sizeOfArguments != requiredSizeOfArguments) + throw new ArgumentOutOfRangeException(nameof(sizeOfArguments), $"Required size does not equal to provided: {requiredSizeOfArguments} > {sizeOfArguments}"); + if (codeStream.ReadByteFully() != 0) + throw new ArgumentException("INVOKEINTERFACE 4th byte is not 0"); } + else { + methodReferenceEntry = readerState.ConstantPool.GetEntry( + Binary.BigEndian.ReadUInt16(codeStream)); + } + + instructions.Add(currentPosition, new MethodInstruction(opcode) { + Owner = new ClassName(methodReferenceEntry.Class.Name.String), + Descriptor = MethodDescriptor.Parse(methodReferenceEntry.NameAndType.Descriptor.String), + Name = methodReferenceEntry.NameAndType.Name.String + }); + } break; case Opcode.GETFIELD: case Opcode.GETSTATIC: case Opcode.PUTFIELD: case Opcode.PUTSTATIC: - var fieldReferenceEntry = readerState.ConstantPool.GetEntry( - Binary.BigEndian.ReadUInt16(codeStream)); - instructions.Add(currentPosition, new FieldInstruction(opcode) - { + FieldReferenceEntry fieldReferenceEntry = readerState.ConstantPool.GetEntry( + Binary.BigEndian.ReadUInt16(codeStream)); + instructions.Add(currentPosition, new FieldInstruction(opcode) { Owner = new ClassName(fieldReferenceEntry.Class.Name.String), Descriptor = TypeDescriptor.Parse(fieldReferenceEntry.NameAndType.Descriptor.String), Name = fieldReferenceEntry.NameAndType.Name.String }); break; - case Opcode.LDC: - { - var constantPoolEntry = - readerState.ConstantPool.GetEntry(codeStream.ReadByteFully()); - instructions.Add(currentPosition, new LdcInstruction - { - Value = constantPoolEntry switch - { - IntegerEntry integerEntry => integerEntry.Value, - FloatEntry floatEntry => floatEntry.Value, - StringEntry stringEntry => stringEntry.Value.String, - ClassEntry classEntry => new ClassName(classEntry.Name.String), - MethodTypeEntry methodTypeEntry => MethodDescriptor.Parse(methodTypeEntry.Descriptor.String), - MethodHandleEntry methodHandleEntry => Handle.FromConstantPool(methodHandleEntry), - _ => throw new ArgumentOutOfRangeException(nameof(constantPoolEntry), - $"Tried to {opcode} wrong type of CP entry: {constantPoolEntry.Tag}") - } - }); + case Opcode.LDC: { + Entry constantPoolEntry = readerState.ConstantPool.GetEntry(codeStream.ReadByteFully()); + + object ldcVal; + switch (constantPoolEntry) { + case IntegerEntry ie: ldcVal = ie.Value; break; + case FloatEntry fe: ldcVal = fe.Value; break; + case StringEntry se: ldcVal = se.Value.String; break; + case ClassEntry ce: ldcVal = new ClassName(ce.Name.String); break; + case MethodTypeEntry mte: ldcVal = MethodDescriptor.Parse(mte.Descriptor.String); break; + case MethodHandleEntry mhe: ldcVal = Handle.FromConstantPool(mhe); break; + default: throw new ArgumentOutOfRangeException(nameof(constantPoolEntry), $"Tried to {opcode} wrong type of CP entry: {constantPoolEntry.Tag}"); } + + instructions.Add(currentPosition, new LdcInstruction {Value = ldcVal}); + } break; case Opcode.LDC_W: - case Opcode.LDC2_W: - { - var constantPoolEntry = - readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(codeStream)); - instructions.Add(currentPosition, new LdcInstruction - { - Value = constantPoolEntry switch - { - IntegerEntry integerEntry when opcode == Opcode.LDC_W => integerEntry.Value, - FloatEntry floatEntry when opcode == Opcode.LDC_W => floatEntry.Value, - StringEntry stringEntry when opcode == Opcode.LDC_W => stringEntry.Value.String, - ClassEntry classEntry when opcode == Opcode.LDC_W => new ClassName(classEntry.Name - .String), - MethodTypeEntry methodTypeEntry when opcode == Opcode.LDC_W => MethodDescriptor.Parse( - methodTypeEntry.Descriptor.String), - MethodHandleEntry methodHandleEntry when opcode == Opcode.LDC_W => new Handle - { - Descriptor = methodHandleEntry.ReferenceKind.IsFieldReference() - ? (IDescriptor) TypeDescriptor.Parse(methodHandleEntry.Reference.NameAndType - .Descriptor.String) - : (IDescriptor) MethodDescriptor.Parse(methodHandleEntry.Reference.NameAndType - .Descriptor.String), - Name = methodHandleEntry.Reference.NameAndType.Name.String, - Owner = new ClassName(methodHandleEntry.Reference.Class.Name.String) - }, - DoubleEntry doubleEntry when opcode == Opcode.LDC2_W => doubleEntry.Value, - LongEntry longEntry when opcode == Opcode.LDC2_W => longEntry.Value, - _ => throw new ArgumentOutOfRangeException(nameof(constantPoolEntry), - $"Tried to {opcode} wrong type of CP entry: {constantPoolEntry.GetType()}") - } - }); + case Opcode.LDC2_W: { + Entry constantPoolEntry = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(codeStream)); + object ldcValue; + switch (constantPoolEntry) { + case IntegerEntry ie when opcode == Opcode.LDC_W: ldcValue = ie.Value; break; + case FloatEntry fe when opcode == Opcode.LDC_W: ldcValue = fe.Value; break; + case StringEntry se when opcode == Opcode.LDC_W: ldcValue = se.Value.String; break; + case ClassEntry ce when opcode == Opcode.LDC_W: ldcValue = new ClassName(ce.Name.String); break; + case MethodTypeEntry mte when opcode == Opcode.LDC_W: ldcValue = MethodDescriptor.Parse(mte.Descriptor.String); break; + case MethodHandleEntry mhe when opcode == Opcode.LDC_W: ldcValue = new Handle {Descriptor = mhe.ReferenceKind.IsFieldReference() ? TypeDescriptor.Parse(mhe.Reference.NameAndType.Descriptor.String) : (IDescriptor) MethodDescriptor.Parse(mhe.Reference.NameAndType.Descriptor.String), Name = mhe.Reference.NameAndType.Name.String, Owner = new ClassName(mhe.Reference.Class.Name.String)}; break; + case DoubleEntry de when opcode == Opcode.LDC2_W: ldcValue = de.Value; break; + case LongEntry le when opcode == Opcode.LDC2_W: ldcValue = le.Value; break; + default: throw new ArgumentOutOfRangeException(nameof(constantPoolEntry), $"Tried to {opcode} wrong type of CP entry: {constantPoolEntry.GetType()}"); } + + instructions.Add(currentPosition, new LdcInstruction { + Value = ldcValue + }); + } break; - case Opcode.None: - throw new ArgumentOutOfRangeException(nameof(opcode), "wut?!"); + case Opcode.None: throw new ArgumentOutOfRangeException(nameof(opcode), "wut?!"); - case Opcode.BREAKPOINT: - throw new ArgumentOutOfRangeException(nameof(opcode), $"Opcode {opcode} is currently not supported"); + case Opcode.BREAKPOINT: throw new ArgumentOutOfRangeException(nameof(opcode), $"Opcode {opcode} is currently not supported"); case Opcode.WIDE: wideFlag = true; continue; - default: - throw new ArgumentOutOfRangeException(nameof(opcode)); + default: throw new ArgumentOutOfRangeException(nameof(opcode)); } if (wideFlag) @@ -551,7 +492,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade parseTo.TryCatches.Capacity = codeAttribute.ExceptionTable.Count; - foreach (var exceptionTableEntry in codeAttribute.ExceptionTable) + foreach (CodeAttribute.ExceptionTableEntry exceptionTableEntry in codeAttribute.ExceptionTable) { parseTo.TryCatches.Add(new TryCatchNode { @@ -562,29 +503,29 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade }); } - var instructionList = instructions.OrderBy(x => x.Key).ToList(); + List> instructionList = instructions.OrderBy(x => x.Key).ToList(); - var labelList = labels.OrderBy(x => x.Key).ToList(); - var labelListPosition = 0; + List> labelList = labels.OrderBy(x => x.Key).ToList(); + int labelListPosition = 0; - var lineNumberTable = ((GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.LineNumberTable)?.ParsedAttribute + List lineNumberTable = ((GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.LineNumberTable)?.ParsedAttribute as LineNumberTableAttribute)?.LineNumberTable ?? new List()).OrderBy(x => x.StartPc).ToList(); if (lineNumberTable.Any(position => !instructions.ContainsKey(position.StartPc))) throw new ArgumentException("Line number is not at the beginning of instruction"); - var lineNumberTablePosition = 0; + int lineNumberTablePosition = 0; - var stackMapFrames = new List<(int Position, StackMapFrame Frame)>(); - var stackMapFramesPosition = 0; + List<(int Position, StackMapFrame Frame)> stackMapFrames = new List<(int Position, StackMapFrame Frame)>(); + int stackMapFramesPosition = 0; { - var stackMapTable = (GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.StackMapTable)?.ParsedAttribute + List stackMapTable = (GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.StackMapTable)?.ParsedAttribute as StackMapTableAttribute)?.Entries; if (stackMapTable != null) { stackMapFrames.Capacity = stackMapTable.Count; - var position = 0; - var hasProcessedFirst = false; - foreach (var entry in stackMapTable) + int position = 0; + bool hasProcessedFirst = false; + foreach (StackMapTableAttribute.StackMapFrame entry in stackMapTable) { VerificationElement ConvertVerificationElement(StackMapTableAttribute.VerificationElement sourceVerificationElement) { @@ -603,7 +544,7 @@ VerificationElement ConvertVerificationElement(StackMapTableAttribute.Verificati break; case StackMapTableAttribute.UninitializedVerificationElement uninitializedVerificationElement: { - var newInstruction = instructions[uninitializedVerificationElement.NewInstructionOffset]; + Instruction newInstruction = instructions[uninitializedVerificationElement.NewInstructionOffset]; if (newInstruction.Opcode != Opcode.NEW) throw new ArgumentException( $"New instruction required by verification element is not NEW: {newInstruction.Opcode}", nameof(newInstruction)); @@ -623,7 +564,7 @@ VerificationElement ConvertVerificationElement(StackMapTableAttribute.Verificati position += entry.OffsetDelta + (hasProcessedFirst ? 1 : 0); - var stackMapFrame = new StackMapFrame + StackMapFrame stackMapFrame = new StackMapFrame { Type = (FrameType) entry.Type, ChopK = entry.ChopK @@ -647,19 +588,19 @@ VerificationElement ConvertVerificationElement(StackMapTableAttribute.Verificati GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.LocalVariableTypeTable); } - foreach (var (position, instruction) in instructionList) + foreach (KeyValuePair pair in instructionList) { while (lineNumberTablePosition < lineNumberTable.Count && - position >= lineNumberTable[lineNumberTablePosition].StartPc) + pair.Key >= lineNumberTable[lineNumberTablePosition].StartPc) parseTo.Instructions.Add(new LineNumber { Line = lineNumberTable[lineNumberTablePosition++].LineNumber }); - while (labelListPosition < labelList.Count && position >= labelList[labelListPosition].Key) + while (labelListPosition < labelList.Count && pair.Key >= labelList[labelListPosition].Key) parseTo.Instructions.Add(labelList[labelListPosition++].Value); - while (stackMapFramesPosition < stackMapFrames.Count && position >= stackMapFrames[stackMapFramesPosition].Position) + while (stackMapFramesPosition < stackMapFrames.Count && pair.Key >= stackMapFrames[stackMapFramesPosition].Position) parseTo.Instructions.Add(stackMapFrames[stackMapFramesPosition++].Frame); - parseTo.Instructions.Add(instruction); + parseTo.Instructions.Add(pair.Value); } while (labelListPosition < labelList.Count) parseTo.Instructions.Add(labelList[labelListPosition++].Value); @@ -669,14 +610,14 @@ VerificationElement ConvertVerificationElement(StackMapTableAttribute.Verificati public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterState writerState) { - var codeAttribute = new CodeAttribute + CodeAttribute codeAttribute = new CodeAttribute { Attributes = source.CodeAttributes, MaxLocals = source.MaxLocals, MaxStack = source.MaxStack }; - foreach (var instruction in source.Instructions) + foreach (Instruction instruction in source.Instructions) { switch (instruction) { @@ -696,24 +637,26 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(typeInstruction.Type.Name))); break; case LdcInstruction ldcInstruction: - writerState.ConstantPool.Find(ldcInstruction.Value switch - { - int integerValue => new IntegerEntry(integerValue), - float floatValue => new FloatEntry(floatValue), - string stringValue => new StringEntry(new Utf8Entry(stringValue)), - long longValue => new LongEntry(longValue), - double doubleValue => new DoubleEntry(doubleValue), - ClassName className => new ClassEntry(new Utf8Entry(className.Name)), - Handle handle => handle.ToConstantPool(), - MethodDescriptor methodDescriptor => new MethodTypeEntry(new Utf8Entry(methodDescriptor.ToString())), - _ => throw new ArgumentOutOfRangeException(nameof(ldcInstruction.Value), $"Can't encode value of type {ldcInstruction.Value.GetType()}") - }); + Entry entry; + switch (ldcInstruction.Value) { + case int integerValue: entry = new IntegerEntry(integerValue); break; + case float floatValue: entry = new FloatEntry(floatValue); break; + case string stringValue: entry = new StringEntry(new Utf8Entry(stringValue)); break; + case long longValue: entry = new LongEntry(longValue); break; + case double doubleValue: entry = new DoubleEntry(doubleValue); break; + case ClassName className: entry = new ClassEntry(new Utf8Entry(className.Name)); break; + case Handle handle: entry = handle.ToConstantPool(); break; + case MethodDescriptor methodDescriptor: entry = new MethodTypeEntry(new Utf8Entry(methodDescriptor.ToString())); break; + default: throw new ArgumentOutOfRangeException(nameof(ldcInstruction.Value), $"Can't encode value of type {ldcInstruction.Value.GetType()}"); + } + + writerState.ConstantPool.Find(entry); break; case MultiANewArrayInstruction multiANewArrayInstruction: writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(multiANewArrayInstruction.Type.Name))); break; case InvokeDynamicInstruction invokeDynamicInstruction: - var bootstrapMethodAttributeNode = + AttributeNode bootstrapMethodAttributeNode = writerState.ClassNode.Attributes.FirstOrDefault(x => x.Name == PredefinedAttributeNames.BootstrapMethods); if (bootstrapMethodAttributeNode == null) @@ -724,7 +667,7 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat }); if (!(bootstrapMethodAttributeNode.ParsedAttribute is BootstrapMethodsAttribute bootstrapMethodAttribute)) throw new Exception("BootstrapMethods attribute exists, but in not-parsed state"); - var bootstrapMethod = new BootstrapMethod(invokeDynamicInstruction.BootstrapMethod, invokeDynamicInstruction.BootstrapMethodArgs); + BootstrapMethod bootstrapMethod = new BootstrapMethod(invokeDynamicInstruction.BootstrapMethod, invokeDynamicInstruction.BootstrapMethodArgs); if (!bootstrapMethodAttribute.BootstrapMethods.Contains(bootstrapMethod)) bootstrapMethodAttribute.BootstrapMethods.Add(bootstrapMethod); writerState.ConstantPool.Find(new InvokeDynamicEntry((ushort) bootstrapMethodAttribute.BootstrapMethods.FindIndex(x => x.Equals(bootstrapMethod)), @@ -748,15 +691,15 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat } } - var lineNumbers = new List(); + List lineNumbers = new List(); - var stackMapFrames = new List(); - var previousStackMapFramePosition = -1; + List stackMapFrames = new List(); + int previousStackMapFramePosition = -1; - var instructions = new Dictionary(); + Dictionary instructions = new Dictionary(); - var currentPosition = 0; - foreach (var instruction in source.Instructions) + int currentPosition = 0; + foreach (Instruction instruction in source.Instructions) { instructions.Add(instruction, (ushort) currentPosition); currentPosition += instruction.Opcode == Opcode.None ? 0 : sizeof(byte); @@ -772,7 +715,7 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat currentPosition += sizeof(ushort); break; case IncrementInstruction incrementInstruction: - currentPosition += incrementInstruction.VariableIndex > byte.MaxValue || + currentPosition += incrementInstruction.VariableIndex > byte.MaxValue || incrementInstruction.Value > sbyte.MaxValue || incrementInstruction.Value < sbyte.MinValue ? sizeof(ushort) * 2 + sizeof(byte) : sizeof(byte) * 2; @@ -790,18 +733,29 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat currentPosition += sizeof(ushort); else { - var constantPoolEntryIndex = ldcInstruction.Value switch - { - int integerValue => writerState.ConstantPool.Find(new IntegerEntry(integerValue)), - float floatValue => writerState.ConstantPool.Find(new FloatEntry(floatValue)), - string stringValue => writerState.ConstantPool.Find( - new StringEntry(new Utf8Entry(stringValue))), - ClassName className => writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(className.Name))), - Handle handle => writerState.ConstantPool.Find(handle.ToConstantPool()), - MethodDescriptor methodDescriptor => writerState.ConstantPool.Find(new MethodTypeEntry(new Utf8Entry(methodDescriptor.ToString()))), - _ => throw new ArgumentOutOfRangeException(nameof(ldcInstruction.Value), - $"Can't encode value of type {ldcInstruction.Value.GetType()}") - }; + ushort constantPoolEntryIndex; + switch (ldcInstruction.Value) { + case int integerValue: + constantPoolEntryIndex = writerState.ConstantPool.Find(new IntegerEntry(integerValue)); + break; + case float floatValue: + constantPoolEntryIndex = writerState.ConstantPool.Find(new FloatEntry(floatValue)); + break; + case string stringValue: + constantPoolEntryIndex = writerState.ConstantPool.Find(new StringEntry(new Utf8Entry(stringValue))); + break; + case ClassName className: + constantPoolEntryIndex = writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(className.Name))); + break; + case Handle handle: + constantPoolEntryIndex = writerState.ConstantPool.Find(handle.ToConstantPool()); + break; + case MethodDescriptor methodDescriptor: + constantPoolEntryIndex = writerState.ConstantPool.Find(new MethodTypeEntry(new Utf8Entry(methodDescriptor.ToString()))); + break; + default: throw new ArgumentOutOfRangeException(nameof(ldcInstruction.Value), $"Can't encode value of type {ldcInstruction.Value.GetType()}"); + } + currentPosition += constantPoolEntryIndex > byte.MaxValue ? sizeof(ushort) : sizeof(byte); } break; @@ -865,7 +819,7 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat } codeAttribute.ExceptionTable.Capacity = source.TryCatches.Count; - foreach (var tryCatchNode in source.TryCatches) + foreach (TryCatchNode tryCatchNode in source.TryCatches) { codeAttribute.ExceptionTable.Add(new CodeAttribute.ExceptionTableEntry { @@ -876,11 +830,11 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat }); } - using var codeDataStream = new MemoryStream(currentPosition); + MemoryStream codeDataStream = new MemoryStream(currentPosition); - foreach (var instruction in source.Instructions) + foreach (Instruction instruction in source.Instructions) { - var position = (ushort) codeDataStream.Position; + ushort position = (ushort) codeDataStream.Position; if (position != instructions[instruction]) throw new Exception($"Wrong position: {position} != {instructions[instruction]}"); @@ -902,11 +856,11 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat new NameAndTypeEntry(new Utf8Entry(methodInstruction.Name), new Utf8Entry(methodInstruction.Descriptor.ToString()))))); if (methodInstruction.Descriptor.ArgumentTypes.Sum(x => x.SizeOnStack) + 1 > byte.MaxValue) - throw new ArgumentOutOfRangeException(nameof(methodInstruction.Descriptor.ArgumentTypes.Count), + throw new ArgumentOutOfRangeException(nameof(methodInstruction.Descriptor.ArgumentTypes.Count), $"Too many arguments: {methodInstruction.Descriptor.ArgumentTypes.Sum(x => x.SizeOnStack) + 1} > {byte.MaxValue}"); codeDataStream.WriteByte((byte) (methodInstruction.Descriptor.ArgumentTypes.Sum(x => x.SizeOnStack) + 1)); codeDataStream.WriteByte(0); - } + } else { Binary.BigEndian.Write(codeDataStream, writerState.ConstantPool.Find(new MethodReferenceEntry( @@ -948,20 +902,35 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat Binary.BigEndian.Write(codeDataStream, (short) (instructions[jumpInstruction.Target] - instructions[jumpInstruction])); break; case LdcInstruction ldcInstruction: - var constantPoolEntryIndex = ldcInstruction.Value switch - { - int integerValue => writerState.ConstantPool.Find(new IntegerEntry(integerValue)), - float floatValue => writerState.ConstantPool.Find(new FloatEntry(floatValue)), - string stringValue => writerState.ConstantPool.Find( - new StringEntry(new Utf8Entry(stringValue))), - long longValue => writerState.ConstantPool.Find(new LongEntry(longValue)), - double doubleValue => writerState.ConstantPool.Find(new DoubleEntry(doubleValue)), - ClassName className => writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(className.Name))), - Handle handle => writerState.ConstantPool.Find(handle.ToConstantPool()), - MethodDescriptor methodDescriptor => writerState.ConstantPool.Find(new MethodTypeEntry(new Utf8Entry(methodDescriptor.ToString()))), - _ => throw new ArgumentOutOfRangeException(nameof(ldcInstruction.Value), - $"Can't encode value of type {ldcInstruction.Value.GetType()}") - }; + ushort constantPoolEntryIndex; + switch (ldcInstruction.Value) { + case int integerValue: + constantPoolEntryIndex = writerState.ConstantPool.Find(new IntegerEntry(integerValue)); + break; + case float floatValue: + constantPoolEntryIndex = writerState.ConstantPool.Find(new FloatEntry(floatValue)); + break; + case string stringValue: + constantPoolEntryIndex = writerState.ConstantPool.Find(new StringEntry(new Utf8Entry(stringValue))); + break; + case long longValue: + constantPoolEntryIndex = writerState.ConstantPool.Find(new LongEntry(longValue)); + break; + case double doubleValue: + constantPoolEntryIndex = writerState.ConstantPool.Find(new DoubleEntry(doubleValue)); + break; + case ClassName className: + constantPoolEntryIndex = writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(className.Name))); + break; + case Handle handle: + constantPoolEntryIndex = writerState.ConstantPool.Find(handle.ToConstantPool()); + break; + case MethodDescriptor methodDescriptor: + constantPoolEntryIndex = writerState.ConstantPool.Find(new MethodTypeEntry(new Utf8Entry(methodDescriptor.ToString()))); + break; + default: throw new ArgumentOutOfRangeException(nameof(ldcInstruction.Value), $"Can't encode value of type {ldcInstruction.Value.GetType()}"); + } + if (ldcInstruction.Value is long || ldcInstruction.Value is double) { codeDataStream.WriteByte((byte) Opcode.LDC2_W); @@ -982,10 +951,10 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat codeDataStream.WriteByte(0); Binary.BigEndian.Write(codeDataStream, instructions[lookupSwitchInstruction.Default] - position); Binary.BigEndian.Write(codeDataStream, lookupSwitchInstruction.MatchLabels.Count); - foreach (var (key, label) in lookupSwitchInstruction.MatchLabels) + foreach (KeyValuePair pair in lookupSwitchInstruction.MatchLabels) { - Binary.BigEndian.Write(codeDataStream, key); - Binary.BigEndian.Write(codeDataStream, instructions[label] - position); + Binary.BigEndian.Write(codeDataStream, pair.Key); + Binary.BigEndian.Write(codeDataStream, instructions[pair.Value] - position); } break; case MultiANewArrayInstruction multiANewArrayInstruction: @@ -1010,7 +979,7 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat if (tableSwitchInstruction.HighValue - tableSwitchInstruction.LowValue + 1 != tableSwitchInstruction.Labels.Count) throw new ArgumentOutOfRangeException(nameof(tableSwitchInstruction)); - foreach (var label in tableSwitchInstruction.Labels) + foreach (Label label in tableSwitchInstruction.Labels) Binary.BigEndian.Write(codeDataStream, instructions[label] - position); break; case VariableInstruction variableInstruction: @@ -1066,11 +1035,11 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat break; case InvokeDynamicInstruction invokeDynamicInstruction: codeDataStream.WriteByte((byte) invokeDynamicInstruction.Opcode); - var bootstrapMethodAttribute = + BootstrapMethodsAttribute bootstrapMethodAttribute = writerState.ClassNode.Attributes.FirstOrDefault(x => x.Name == PredefinedAttributeNames.BootstrapMethods).ParsedAttribute as BootstrapMethodsAttribute; - var bootstrapMethod = new BootstrapMethod(invokeDynamicInstruction.BootstrapMethod, invokeDynamicInstruction.BootstrapMethodArgs); + BootstrapMethod bootstrapMethod = new BootstrapMethod(invokeDynamicInstruction.BootstrapMethod, invokeDynamicInstruction.BootstrapMethodArgs); Binary.BigEndian.Write(codeDataStream, writerState.ConstantPool.Find(new InvokeDynamicEntry( (ushort) bootstrapMethodAttribute.BootstrapMethods.FindIndex(x => x.Equals(bootstrapMethod)), new NameAndTypeEntry(new Utf8Entry(invokeDynamicInstruction.Name), diff --git a/JavaAsm/Instructions/Types/FieldInstruction.cs b/JavaAsm/Instructions/Types/FieldInstruction.cs index 02116b6..08d8e15 100644 --- a/JavaAsm/Instructions/Types/FieldInstruction.cs +++ b/JavaAsm/Instructions/Types/FieldInstruction.cs @@ -16,12 +16,12 @@ public FieldInstruction(Opcode opcode) { opcode.CheckInAndThrow(nameof(opcode), Opcode.GETFIELD, Opcode.GETSTATIC, Opcode.PUTFIELD, Opcode.PUTSTATIC); - Opcode = opcode; + this.Opcode = opcode; } public override string ToString() { - return $"{Opcode} {Owner}.{Name} {Descriptor}"; + return $"{this.Opcode} {this.Owner}.{this.Name} {this.Descriptor}"; } } } diff --git a/JavaAsm/Instructions/Types/IncrementInstruction.cs b/JavaAsm/Instructions/Types/IncrementInstruction.cs index 5e04293..20bcd6c 100644 --- a/JavaAsm/Instructions/Types/IncrementInstruction.cs +++ b/JavaAsm/Instructions/Types/IncrementInstruction.cs @@ -10,7 +10,7 @@ public class IncrementInstruction : Instruction public override string ToString() { - return $"{Opcode} {VariableIndex} {Value}"; + return $"{this.Opcode} {this.VariableIndex} {this.Value}"; } } } diff --git a/JavaAsm/Instructions/Types/IntegerPushInstruction.cs b/JavaAsm/Instructions/Types/IntegerPushInstruction.cs index 27e369d..7d6b158 100644 --- a/JavaAsm/Instructions/Types/IntegerPushInstruction.cs +++ b/JavaAsm/Instructions/Types/IntegerPushInstruction.cs @@ -11,12 +11,12 @@ public class IntegerPushInstruction : Instruction public IntegerPushInstruction(Opcode opcode) { opcode.CheckInAndThrow(nameof(opcode), Opcode.BIPUSH, Opcode.SIPUSH); - Opcode = opcode; + this.Opcode = opcode; } public override string ToString() { - return $"{Opcode} {Value}"; + return $"{this.Opcode} {this.Value}"; } } } diff --git a/JavaAsm/Instructions/Types/InvokeDynamicInstruction.cs b/JavaAsm/Instructions/Types/InvokeDynamicInstruction.cs index 4e99327..1669c00 100644 --- a/JavaAsm/Instructions/Types/InvokeDynamicInstruction.cs +++ b/JavaAsm/Instructions/Types/InvokeDynamicInstruction.cs @@ -58,24 +58,31 @@ internal static Handle FromConstantPool(MethodHandleEntry methodHandleEntry) internal MethodHandleEntry ToConstantPool() { - var referenceOwner = new ClassEntry(new Utf8Entry(Owner.Name)); - var referenceNameAndType = new NameAndTypeEntry(new Utf8Entry(Name), new Utf8Entry(Descriptor.ToString())); - var reference = Type switch - { - ReferenceKindType.GetField => (ReferenceEntry) new FieldReferenceEntry(referenceOwner, - referenceNameAndType), - ReferenceKindType.GetStatic => new FieldReferenceEntry(referenceOwner, referenceNameAndType), - ReferenceKindType.PutField => new FieldReferenceEntry(referenceOwner, referenceNameAndType), - ReferenceKindType.PutStatic => new FieldReferenceEntry(referenceOwner, referenceNameAndType), - ReferenceKindType.InvokeVirtual => new MethodReferenceEntry(referenceOwner, referenceNameAndType), - ReferenceKindType.NewInvokeSpecial => new MethodReferenceEntry(referenceOwner, referenceNameAndType), - ReferenceKindType.InvokeStatic => new MethodReferenceEntry(referenceOwner, referenceNameAndType), - ReferenceKindType.InvokeSpecial => new MethodReferenceEntry(referenceOwner, referenceNameAndType), - ReferenceKindType.InvokeReference => new InterfaceMethodReferenceEntry(referenceOwner, - referenceNameAndType), - _ => throw new ArgumentOutOfRangeException(nameof(Type)) - }; - return new MethodHandleEntry(Type, reference); + ClassEntry referenceOwner = new ClassEntry(new Utf8Entry(this.Owner.Name)); + NameAndTypeEntry referenceNameAndType = new NameAndTypeEntry(new Utf8Entry(this.Name), new Utf8Entry(this.Descriptor.ToString())); + ReferenceEntry reference; + switch (this.Type) { + case ReferenceKindType.GetField: + reference = new FieldReferenceEntry(referenceOwner, referenceNameAndType); + break; + case ReferenceKindType.GetStatic: + case ReferenceKindType.PutField: + case ReferenceKindType.PutStatic: + reference = new FieldReferenceEntry(referenceOwner, referenceNameAndType); + break; + case ReferenceKindType.InvokeVirtual: + case ReferenceKindType.NewInvokeSpecial: + case ReferenceKindType.InvokeStatic: + case ReferenceKindType.InvokeSpecial: + reference = new MethodReferenceEntry(referenceOwner, referenceNameAndType); + break; + case ReferenceKindType.InvokeReference: + reference = new InterfaceMethodReferenceEntry(referenceOwner, referenceNameAndType); + break; + default: throw new ArgumentOutOfRangeException(nameof(this.Type)); + } + + return new MethodHandleEntry(this.Type, reference); } } } diff --git a/JavaAsm/Instructions/Types/JumpInstruction.cs b/JavaAsm/Instructions/Types/JumpInstruction.cs index bbb766a..1a9d86a 100644 --- a/JavaAsm/Instructions/Types/JumpInstruction.cs +++ b/JavaAsm/Instructions/Types/JumpInstruction.cs @@ -7,18 +7,18 @@ public class JumpInstruction : Instruction public override Opcode Opcode { get; } public Label Target { get; set; } - + public JumpInstruction(Opcode opcode) { opcode.CheckInAndThrow(nameof(opcode), Opcode.IFEQ, Opcode.IFNE, Opcode.IFLT, Opcode.IFGE, Opcode.IFGT, Opcode.IFLE, Opcode.IF_ICMPEQ, Opcode.IF_ICMPNE, Opcode.IF_ICMPLT, Opcode.IF_ICMPGE, Opcode.IF_ICMPGT, Opcode.IF_ICMPLE, Opcode.IF_ACMPEQ, Opcode.IF_ACMPNE, Opcode.GOTO, Opcode.JSR, Opcode.IFNULL, Opcode.IFNONNULL); - Opcode = opcode; + this.Opcode = opcode; } public override string ToString() { - return $"{Opcode} L{Target.Index}"; + return $"{this.Opcode} L{this.Target.Index}"; } } } diff --git a/JavaAsm/Instructions/Types/Label.cs b/JavaAsm/Instructions/Types/Label.cs index a3b0f3a..0351990 100644 --- a/JavaAsm/Instructions/Types/Label.cs +++ b/JavaAsm/Instructions/Types/Label.cs @@ -10,12 +10,12 @@ public class Label : Instruction public Label() { - Index = globalLabelIndex++; + this.Index = globalLabelIndex++; } public override string ToString() { - return $"LABEL L{Index}"; + return $"LABEL L{this.Index}"; } } } diff --git a/JavaAsm/Instructions/Types/LdcInstruction.cs b/JavaAsm/Instructions/Types/LdcInstruction.cs index e288bd4..8fed518 100644 --- a/JavaAsm/Instructions/Types/LdcInstruction.cs +++ b/JavaAsm/Instructions/Types/LdcInstruction.cs @@ -8,10 +8,10 @@ public class LdcInstruction : Instruction public override string ToString() { - var stringValue = Value.ToString(); - if (Value is string) + string stringValue = this.Value.ToString(); + if (this.Value is string) stringValue = $"\"{stringValue}\""; - return $"{Opcode} {stringValue}"; + return $"{this.Opcode} {stringValue}"; } } } diff --git a/JavaAsm/Instructions/Types/LineNumber.cs b/JavaAsm/Instructions/Types/LineNumber.cs index f466e18..925eb42 100644 --- a/JavaAsm/Instructions/Types/LineNumber.cs +++ b/JavaAsm/Instructions/Types/LineNumber.cs @@ -8,7 +8,7 @@ public class LineNumber : Instruction public override string ToString() { - return $"LINE {Line}"; + return $"LINE {this.Line}"; } } } diff --git a/JavaAsm/Instructions/Types/MethodInstruction.cs b/JavaAsm/Instructions/Types/MethodInstruction.cs index e5cacf4..d79fc0d 100644 --- a/JavaAsm/Instructions/Types/MethodInstruction.cs +++ b/JavaAsm/Instructions/Types/MethodInstruction.cs @@ -16,11 +16,11 @@ public MethodInstruction(Opcode opcode) { opcode.CheckInAndThrow(nameof(opcode), Opcode.INVOKESTATIC, Opcode.INVOKEVIRTUAL, Opcode.INVOKEINTERFACE, Opcode.INVOKESPECIAL); - Opcode = opcode; + this.Opcode = opcode; } public override string ToString() { - return $"{Opcode} {Owner}.{Name}{Descriptor}"; + return $"{this.Opcode} {this.Owner}.{this.Name}{this.Descriptor}"; } } } \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/MultiANewArrayInstruction.cs b/JavaAsm/Instructions/Types/MultiANewArrayInstruction.cs index 11ada67..0fd2f6e 100644 --- a/JavaAsm/Instructions/Types/MultiANewArrayInstruction.cs +++ b/JavaAsm/Instructions/Types/MultiANewArrayInstruction.cs @@ -10,7 +10,7 @@ public class MultiANewArrayInstruction : Instruction public override string ToString() { - return $"{Opcode} {Type} {Dimensions}"; + return $"{this.Opcode} {this.Type} {this.Dimensions}"; } } } diff --git a/JavaAsm/Instructions/Types/NewArrayInstruction.cs b/JavaAsm/Instructions/Types/NewArrayInstruction.cs index fa72d0c..8975449 100644 --- a/JavaAsm/Instructions/Types/NewArrayInstruction.cs +++ b/JavaAsm/Instructions/Types/NewArrayInstruction.cs @@ -8,7 +8,7 @@ public class NewArrayInstruction : Instruction public override string ToString() { - return $"{Opcode} {ArrayType}"; + return $"{this.Opcode} {this.ArrayType}"; } } diff --git a/JavaAsm/Instructions/Types/SimpleInstruction.cs b/JavaAsm/Instructions/Types/SimpleInstruction.cs index 193420a..1cd3da4 100644 --- a/JavaAsm/Instructions/Types/SimpleInstruction.cs +++ b/JavaAsm/Instructions/Types/SimpleInstruction.cs @@ -8,28 +8,28 @@ public class SimpleInstruction : Instruction public SimpleInstruction(Opcode opcode) { - opcode.CheckInAndThrow(nameof(opcode), - Opcode.NOP, Opcode.ACONST_NULL, Opcode.ICONST_M1, Opcode.ICONST_0, Opcode.ICONST_1, Opcode.ICONST_2, - Opcode.ICONST_3, Opcode.ICONST_4, Opcode.ICONST_5, Opcode.LCONST_0, Opcode.LCONST_1, Opcode.FCONST_0, + opcode.CheckInAndThrow(nameof(opcode), + Opcode.NOP, Opcode.ACONST_NULL, Opcode.ICONST_M1, Opcode.ICONST_0, Opcode.ICONST_1, Opcode.ICONST_2, + Opcode.ICONST_3, Opcode.ICONST_4, Opcode.ICONST_5, Opcode.LCONST_0, Opcode.LCONST_1, Opcode.FCONST_0, Opcode.FCONST_1, Opcode.FCONST_2, Opcode.DCONST_0, Opcode.DCONST_1, Opcode.IALOAD, Opcode.LALOAD, Opcode.FALOAD, - Opcode.DALOAD, Opcode.AALOAD, Opcode.BALOAD, Opcode.CALOAD, Opcode.SALOAD, Opcode.IASTORE, Opcode.LASTORE, + Opcode.DALOAD, Opcode.AALOAD, Opcode.BALOAD, Opcode.CALOAD, Opcode.SALOAD, Opcode.IASTORE, Opcode.LASTORE, Opcode.FASTORE, Opcode.DASTORE, Opcode.AASTORE, Opcode.BASTORE, Opcode.CASTORE, Opcode.SASTORE, Opcode.POP, Opcode.POP2, Opcode.DUP, Opcode.DUP_X1, Opcode.DUP_X2, Opcode.DUP2, Opcode.DUP2_X1, Opcode.DUP2_X2, Opcode.SWAP, - Opcode.IADD, Opcode.LADD, Opcode.FADD, Opcode.DADD, Opcode.ISUB, Opcode.LSUB, Opcode.FSUB, Opcode.DSUB, - Opcode.IMUL, Opcode.LMUL, Opcode.FMUL, Opcode.DMUL, Opcode.IDIV, Opcode.LDIV, Opcode.FDIV, Opcode.DDIV, - Opcode.IREM, Opcode.LREM, Opcode.FREM, Opcode.DREM, Opcode.INEG, Opcode.LNEG, Opcode.FNEG, Opcode.DNEG, - Opcode.ISHL, Opcode.LSHL, Opcode.ISHR, Opcode.LSHR, Opcode.IUSHR, Opcode.LUSHR, Opcode.IAND, Opcode.LAND, + Opcode.IADD, Opcode.LADD, Opcode.FADD, Opcode.DADD, Opcode.ISUB, Opcode.LSUB, Opcode.FSUB, Opcode.DSUB, + Opcode.IMUL, Opcode.LMUL, Opcode.FMUL, Opcode.DMUL, Opcode.IDIV, Opcode.LDIV, Opcode.FDIV, Opcode.DDIV, + Opcode.IREM, Opcode.LREM, Opcode.FREM, Opcode.DREM, Opcode.INEG, Opcode.LNEG, Opcode.FNEG, Opcode.DNEG, + Opcode.ISHL, Opcode.LSHL, Opcode.ISHR, Opcode.LSHR, Opcode.IUSHR, Opcode.LUSHR, Opcode.IAND, Opcode.LAND, Opcode.IOR, Opcode.LOR, Opcode.IXOR, Opcode.LXOR, Opcode.I2L, Opcode.I2F, Opcode.I2D, Opcode.L2I, Opcode.L2F, - Opcode.L2D, Opcode.F2I, Opcode.F2L, Opcode.F2D, Opcode.D2I, Opcode.D2L, Opcode.D2F, Opcode.I2B, Opcode.I2C, - Opcode.I2S, Opcode.LCMP, Opcode.FCMPL, Opcode.FCMPG, Opcode.DCMPL, Opcode.DCMPG, Opcode.IRETURN, Opcode.LRETURN, - Opcode.FRETURN, Opcode.DRETURN, Opcode.ARETURN, Opcode.RETURN, Opcode.ARRAYLENGTH, Opcode.ATHROW, + Opcode.L2D, Opcode.F2I, Opcode.F2L, Opcode.F2D, Opcode.D2I, Opcode.D2L, Opcode.D2F, Opcode.I2B, Opcode.I2C, + Opcode.I2S, Opcode.LCMP, Opcode.FCMPL, Opcode.FCMPG, Opcode.DCMPL, Opcode.DCMPG, Opcode.IRETURN, Opcode.LRETURN, + Opcode.FRETURN, Opcode.DRETURN, Opcode.ARETURN, Opcode.RETURN, Opcode.ARRAYLENGTH, Opcode.ATHROW, Opcode.MONITORENTER, Opcode.MONITOREXIT); - Opcode = opcode; + this.Opcode = opcode; } public override string ToString() { - return $"{Opcode}"; + return $"{this.Opcode}"; } } } diff --git a/JavaAsm/Instructions/Types/StackMapFrame.cs b/JavaAsm/Instructions/Types/StackMapFrame.cs index 337472d..8a0641b 100644 --- a/JavaAsm/Instructions/Types/StackMapFrame.cs +++ b/JavaAsm/Instructions/Types/StackMapFrame.cs @@ -29,7 +29,7 @@ public SimpleVerificationElement(VerificationElementType type) { type.CheckInAndThrow(nameof(type), VerificationElementType.Top, VerificationElementType.Integer, VerificationElementType.Float, VerificationElementType.Long, VerificationElementType.Double, VerificationElementType.Null, VerificationElementType.UnitializedThis); - Type = type; + this.Type = type; } } diff --git a/JavaAsm/Instructions/Types/TypeInstruction.cs b/JavaAsm/Instructions/Types/TypeInstruction.cs index 83b5a11..83cf5d4 100644 --- a/JavaAsm/Instructions/Types/TypeInstruction.cs +++ b/JavaAsm/Instructions/Types/TypeInstruction.cs @@ -11,12 +11,12 @@ public class TypeInstruction : Instruction public TypeInstruction(Opcode opcode) { opcode.CheckInAndThrow(nameof(opcode), Opcode.NEW, Opcode.ANEWARRAY, Opcode.CHECKCAST, Opcode.INSTANCEOF); - Opcode = opcode; + this.Opcode = opcode; } public override string ToString() { - return $"{Opcode} {Type}"; + return $"{this.Opcode} {this.Type}"; } } } diff --git a/JavaAsm/Instructions/Types/VariableInstruction.cs b/JavaAsm/Instructions/Types/VariableInstruction.cs index 1af6f09..3ec6f56 100644 --- a/JavaAsm/Instructions/Types/VariableInstruction.cs +++ b/JavaAsm/Instructions/Types/VariableInstruction.cs @@ -12,12 +12,12 @@ public VariableInstruction(Opcode opcode) { opcode.CheckInAndThrow(nameof(opcode), Opcode.ILOAD, Opcode.LLOAD, Opcode.FLOAD, Opcode.DLOAD, Opcode.ALOAD, Opcode.ISTORE, Opcode.LSTORE, Opcode.FSTORE, Opcode.DSTORE, Opcode.ASTORE, Opcode.RET); - Opcode = opcode; + this.Opcode = opcode; } public override string ToString() { - return $"{Opcode} {VariableIndex}"; + return $"{this.Opcode} {this.VariableIndex}"; } } } diff --git a/JavaAsm/JavaAsm.csproj b/JavaAsm/JavaAsm.csproj index ada9ce2..090e31d 100644 --- a/JavaAsm/JavaAsm.csproj +++ b/JavaAsm/JavaAsm.csproj @@ -1,10 +1,18 @@  - netstandard2.1 + netstandard2.0 latest + + true + + + + true + + diff --git a/JavaAsm/MethodDescriptor.cs b/JavaAsm/MethodDescriptor.cs index 6c396b2..a65fdef 100644 --- a/JavaAsm/MethodDescriptor.cs +++ b/JavaAsm/MethodDescriptor.cs @@ -18,7 +18,7 @@ public class MethodDescriptor : IDescriptor /// /// Arguments type descriptors /// - public List ArgumentTypes { get; } + public List ArgumentTypes { get; } /// /// Creates method descriptor @@ -26,7 +26,7 @@ public class MethodDescriptor : IDescriptor /// Return type /// Argument types public MethodDescriptor(TypeDescriptor returnType, params TypeDescriptor[] argumentTypes) : this(returnType, argumentTypes.ToList()) { } - + /// /// Creates method descriptor /// @@ -34,8 +34,8 @@ public MethodDescriptor(TypeDescriptor returnType, params TypeDescriptor[] argum /// Argument types public MethodDescriptor(TypeDescriptor returnType, List argumentTypes) { - ReturnType = returnType ?? throw new ArgumentNullException(nameof(returnType)); - ArgumentTypes = argumentTypes ?? throw new ArgumentNullException(nameof(argumentTypes)); + this.ReturnType = returnType ?? throw new ArgumentNullException(nameof(returnType)); + this.ArgumentTypes = argumentTypes ?? throw new ArgumentNullException(nameof(argumentTypes)); } /// @@ -45,11 +45,11 @@ public MethodDescriptor(TypeDescriptor returnType, List argument /// Parsed method descriptor public static MethodDescriptor Parse(string descriptor) { - var offset = 0; + int offset = 0; if (descriptor[offset] != '(') throw new FormatException($"Wrong method descriptor: {descriptor}"); offset++; - var argumentTypes = new List(); + List argumentTypes = new List(); while (descriptor[offset] != ')') argumentTypes.Add(TypeDescriptor.Parse(descriptor, ref offset)); offset++; @@ -59,18 +59,18 @@ public static MethodDescriptor Parse(string descriptor) /// public override string ToString() { - var result = new StringBuilder(); + StringBuilder result = new StringBuilder(); result.Append('('); - foreach (var argumentType in ArgumentTypes) + foreach (TypeDescriptor argumentType in this.ArgumentTypes) result.Append(argumentType); result.Append(')'); - result.Append(ReturnType); + result.Append(this.ReturnType); return result.ToString(); } private bool Equals(MethodDescriptor other) { - return Equals(ReturnType, other.ReturnType) && Equals(ArgumentTypes, other.ArgumentTypes); + return Equals(this.ReturnType, other.ReturnType) && Equals(this.ArgumentTypes, other.ArgumentTypes); } /// @@ -86,7 +86,7 @@ public override int GetHashCode() { unchecked { - return (ReturnType.GetHashCode() * 397) ^ ArgumentTypes.GetHashCode(); + return (this.ReturnType.GetHashCode() * 397) ^ this.ArgumentTypes.GetHashCode(); } } } diff --git a/JavaAsm/MethodNode.cs b/JavaAsm/MethodNode.cs index 4133f55..ee18f33 100644 --- a/JavaAsm/MethodNode.cs +++ b/JavaAsm/MethodNode.cs @@ -102,9 +102,9 @@ public class MethodNode /// null, if attribute does not exist or AttributeNode if exists private AttributeNode GetAttribute(string name) { - var attribute = Attributes.FirstOrDefault(a => a.Name == name); + AttributeNode attribute = this.Attributes.FirstOrDefault(a => a.Name == name); if (attribute != null) - Attributes.Remove(attribute); + this.Attributes.Remove(attribute); return attribute; } @@ -114,30 +114,30 @@ private AttributeNode GetAttribute(string name) /// Class reader state internal void Parse(ClassReaderState readerState) { - Signature = (GetAttribute(PredefinedAttributeNames.Signature)?.ParsedAttribute as SignatureAttribute)?.Value; + this.Signature = (GetAttribute(PredefinedAttributeNames.Signature)?.ParsedAttribute as SignatureAttribute)?.Value; { - var attribute = GetAttribute(PredefinedAttributeNames.Code); + AttributeNode attribute = GetAttribute(PredefinedAttributeNames.Code); if (attribute?.ParsedAttribute is CodeAttribute codeAttribute) InstructionListConverter.ParseCodeAttribute(this, readerState, codeAttribute); } { - var attribute = GetAttribute(PredefinedAttributeNames.RuntimeInvisibleAnnotations); + AttributeNode attribute = GetAttribute(PredefinedAttributeNames.RuntimeInvisibleAnnotations); if (attribute != null) - InvisibleAnnotations = (attribute.ParsedAttribute as RuntimeInvisibleAnnotationsAttribute)?.Annotations; + this.InvisibleAnnotations = (attribute.ParsedAttribute as RuntimeInvisibleAnnotationsAttribute)?.Annotations; } { - var attribute = GetAttribute(PredefinedAttributeNames.RuntimeVisibleAnnotations); + AttributeNode attribute = GetAttribute(PredefinedAttributeNames.RuntimeVisibleAnnotations); if (attribute != null) - VisibleAnnotations = (attribute.ParsedAttribute as RuntimeVisibleAnnotationsAttribute)?.Annotations; + this.VisibleAnnotations = (attribute.ParsedAttribute as RuntimeVisibleAnnotationsAttribute)?.Annotations; } { - var attribute = GetAttribute(PredefinedAttributeNames.Exceptions); + AttributeNode attribute = GetAttribute(PredefinedAttributeNames.Exceptions); if (attribute != null) - Throws = (attribute.ParsedAttribute as ExceptionsAttribute)?.ExceptionTable; + this.Throws = (attribute.ParsedAttribute as ExceptionsAttribute)?.ExceptionTable; } - AnnotationDefaultValue = + this.AnnotationDefaultValue = (GetAttribute(PredefinedAttributeNames.AnnotationDefault)?.ParsedAttribute as AnnotationDefaultAttribute)?.Value; - IsDeprecated = GetAttribute(PredefinedAttributeNames.Deprecated)?.ParsedAttribute != null; + this.IsDeprecated = GetAttribute(PredefinedAttributeNames.Deprecated)?.ParsedAttribute != null; } /// @@ -146,100 +146,100 @@ internal void Parse(ClassReaderState readerState) /// Class writer state internal void Save(ClassWriterState writerState) { - if (Signature != null) + if (this.Signature != null) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.Signature)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Signature)) throw new Exception( $"{PredefinedAttributeNames.Signature} attribute is already presented on method"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Signature, ParsedAttribute = new SignatureAttribute { - Value = Signature + Value = this.Signature } }); } - if (!Access.HasFlag(MethodAccessModifiers.Abstract) && !Access.HasFlag(MethodAccessModifiers.Native) && Instructions != null) + if (!this.Access.HasFlag(MethodAccessModifiers.Abstract) && !this.Access.HasFlag(MethodAccessModifiers.Native) && this.Instructions != null) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.Code)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Code)) throw new Exception( $"{PredefinedAttributeNames.Code} attribute is already presented on method"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Code, ParsedAttribute = InstructionListConverter.SaveCodeAttribute(this, writerState) }); } - if (InvisibleAnnotations != null && InvisibleAnnotations.Count > 0) + if (this.InvisibleAnnotations != null && this.InvisibleAnnotations.Count > 0) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeInvisibleAnnotations)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeInvisibleAnnotations)) throw new Exception( $"{PredefinedAttributeNames.RuntimeInvisibleAnnotations} attribute is already presented on method"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeInvisibleAnnotations, ParsedAttribute = new RuntimeInvisibleAnnotationsAttribute { - Annotations = InvisibleAnnotations + Annotations = this.InvisibleAnnotations } }); } - if (VisibleAnnotations != null && VisibleAnnotations.Count > 0) + if (this.VisibleAnnotations != null && this.VisibleAnnotations.Count > 0) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeVisibleAnnotations)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeVisibleAnnotations)) throw new Exception( $"{PredefinedAttributeNames.RuntimeVisibleAnnotations} attribute is already presented on method"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeVisibleAnnotations, ParsedAttribute = new RuntimeVisibleAnnotationsAttribute { - Annotations = VisibleAnnotations + Annotations = this.VisibleAnnotations } }); } - if (Throws.Count > 0) + if (this.Throws.Count > 0) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.Exceptions)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Exceptions)) throw new Exception( $"{PredefinedAttributeNames.Exceptions} attribute is already presented on method"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Exceptions, ParsedAttribute = new ExceptionsAttribute { - ExceptionTable = Throws + ExceptionTable = this.Throws } }); } - if (AnnotationDefaultValue != null) + if (this.AnnotationDefaultValue != null) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.AnnotationDefault)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.AnnotationDefault)) throw new Exception( $"{PredefinedAttributeNames.AnnotationDefault} attribute is already presented on method"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.AnnotationDefault, ParsedAttribute = new AnnotationDefaultAttribute { - Value = AnnotationDefaultValue + Value = this.AnnotationDefaultValue } }); } // ReSharper disable once InvertIf - if (IsDeprecated) + if (this.IsDeprecated) { - if (Attributes.Any(x => x.Name == PredefinedAttributeNames.Deprecated)) + if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Deprecated)) throw new Exception( $"{PredefinedAttributeNames.Deprecated} attribute is already presented on method"); - Attributes.Add(new AttributeNode + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Deprecated, ParsedAttribute = new DeprecatedAttribute() @@ -250,7 +250,7 @@ internal void Save(ClassWriterState writerState) /// public override string ToString() { - return $"{AccessModifiersExtensions.ToString(Access)} {Name}{Descriptor}"; + return $"{AccessModifiersExtensions.ToString(this.Access)} {this.Name}{this.Descriptor}"; } } } \ No newline at end of file diff --git a/JavaAsm/TypeDescriptor.cs b/JavaAsm/TypeDescriptor.cs index fa600d0..e0b8a3b 100644 --- a/JavaAsm/TypeDescriptor.cs +++ b/JavaAsm/TypeDescriptor.cs @@ -2,13 +2,11 @@ using System.Linq; using System.Text; -namespace JavaAsm -{ +namespace JavaAsm { /// /// Type descriptor /// - public class TypeDescriptor : IDescriptor - { + public class TypeDescriptor : IDescriptor { /// /// Class name. Equals to null if type is primitive /// @@ -29,10 +27,9 @@ public class TypeDescriptor : IDescriptor /// /// Class /// Array depth - public TypeDescriptor(ClassName className, int arrayDepth) - { - ArrayDepth = arrayDepth; - ClassName = className ?? throw new ArgumentNullException(nameof(className)); + public TypeDescriptor(ClassName className, int arrayDepth) { + this.ArrayDepth = arrayDepth; + this.ClassName = className ?? throw new ArgumentNullException(nameof(className)); } /// @@ -40,10 +37,9 @@ public TypeDescriptor(ClassName className, int arrayDepth) /// /// Primitive type /// Array depth - public TypeDescriptor(PrimitiveType primitiveType, int arrayDepth) - { - ArrayDepth = arrayDepth; - PrimitiveType = primitiveType; + public TypeDescriptor(PrimitiveType primitiveType, int arrayDepth) { + this.ArrayDepth = arrayDepth; + this.PrimitiveType = primitiveType; } /// @@ -52,10 +48,9 @@ public TypeDescriptor(PrimitiveType primitiveType, int arrayDepth) /// Source string to parse from /// Allow void type /// Parsed type descriptor - public static TypeDescriptor Parse(string descriptor, bool allowVoid = false) - { - var offset = 0; - var parsedType = Parse(descriptor, ref offset, allowVoid); + public static TypeDescriptor Parse(string descriptor, bool allowVoid = false) { + int offset = 0; + TypeDescriptor parsedType = Parse(descriptor, ref offset, allowVoid); if (offset != descriptor.Length) throw new FormatException($"Exceed charaters in descriptor: {descriptor}"); return parsedType; @@ -68,19 +63,16 @@ public static TypeDescriptor Parse(string descriptor, bool allowVoid = false) /// Offset in source string to parse from /// Allow void type /// Parsed type descriptor - public static TypeDescriptor Parse(string descriptor, ref int offset, bool allowVoid = false) - { - var arrayDepth = 0; - while (descriptor[offset] == '[') - { + public static TypeDescriptor Parse(string descriptor, ref int offset, bool allowVoid = false) { + int arrayDepth = 0; + while (descriptor[offset] == '[') { arrayDepth++; offset++; } - var typeChar = descriptor[offset]; + char typeChar = descriptor[offset]; PrimitiveType primitiveType; - switch (typeChar) - { + switch (typeChar) { case 'B': primitiveType = global::JavaAsm.PrimitiveType.Byte; break; @@ -111,18 +103,16 @@ public static TypeDescriptor Parse(string descriptor, ref int offset, bool allow primitiveType = global::JavaAsm.PrimitiveType.Void; break; case 'L': - var className = new StringBuilder(); + StringBuilder className = new StringBuilder(); offset++; - while (descriptor[offset] != ';') - { + while (descriptor[offset] != ';') { className.Append(descriptor[offset]); offset++; } offset++; return new TypeDescriptor(new ClassName(className.ToString()), arrayDepth); - default: - throw new ArgumentOutOfRangeException(nameof(typeChar), $"Wrong type char: {typeChar}"); + default: throw new ArgumentOutOfRangeException(nameof(typeChar), $"Wrong type char: {typeChar}"); } offset++; @@ -132,57 +122,51 @@ public static TypeDescriptor Parse(string descriptor, ref int offset, bool allow /// /// Returns size of type on stack /// - public int SizeOnStack => ArrayDepth == 0 && (PrimitiveType == JavaAsm.PrimitiveType.Double || PrimitiveType == JavaAsm.PrimitiveType.Long) ? 2 : - PrimitiveType == JavaAsm.PrimitiveType.Void ? 0 : 1; + public int SizeOnStack => this.ArrayDepth == 0 && (this.PrimitiveType == JavaAsm.PrimitiveType.Double || this.PrimitiveType == JavaAsm.PrimitiveType.Long) ? 2 : this.PrimitiveType == JavaAsm.PrimitiveType.Void ? 0 : 1; /// - public override string ToString() - { - var result = string.Join("", Enumerable.Repeat('[', ArrayDepth)); - if (PrimitiveType == null) - { - result += $"L{ClassName.Name};"; + public override string ToString() { + string result = string.Join("", Enumerable.Repeat('[', this.ArrayDepth)); + if (this.PrimitiveType == null) { + result += $"L{this.ClassName.Name};"; } - else - { - result += PrimitiveType.Value switch - { - global::JavaAsm.PrimitiveType.Boolean => 'Z', - global::JavaAsm.PrimitiveType.Byte => 'B', - global::JavaAsm.PrimitiveType.Character => 'C', - global::JavaAsm.PrimitiveType.Double => 'D', - global::JavaAsm.PrimitiveType.Float => 'F', - global::JavaAsm.PrimitiveType.Integer => 'I', - global::JavaAsm.PrimitiveType.Long => 'J', - global::JavaAsm.PrimitiveType.Short => 'S', - global::JavaAsm.PrimitiveType.Void => 'V', - _ => throw new ArgumentOutOfRangeException(nameof(PrimitiveType.Value)) - }; + else { + switch (this.PrimitiveType.Value) { + case global::JavaAsm.PrimitiveType.Boolean: result += 'Z'; break; + case global::JavaAsm.PrimitiveType.Byte: result += 'B'; break; + case global::JavaAsm.PrimitiveType.Character: result += 'C'; break; + case global::JavaAsm.PrimitiveType.Double: result += 'D'; break; + case global::JavaAsm.PrimitiveType.Float: result += 'F'; break; + case global::JavaAsm.PrimitiveType.Integer: result += 'I'; break; + case global::JavaAsm.PrimitiveType.Long: result += 'J'; break; + case global::JavaAsm.PrimitiveType.Short: result += 'S'; break; + case global::JavaAsm.PrimitiveType.Void: result += 'V'; break; + default: throw new ArgumentOutOfRangeException(nameof(this.PrimitiveType.Value)); + } } + return result; } - private bool Equals(TypeDescriptor other) - { - return ArrayDepth == other.ArrayDepth && Equals(ClassName, other.ClassName) && PrimitiveType == other.PrimitiveType; + private bool Equals(TypeDescriptor other) { + return this.ArrayDepth == other.ArrayDepth && Equals(this.ClassName, other.ClassName) && this.PrimitiveType == other.PrimitiveType; } /// - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; return obj.GetType() == GetType() && Equals((TypeDescriptor) obj); } /// - public override int GetHashCode() - { - unchecked - { - var hashCode = ArrayDepth; - hashCode = (hashCode * 397) ^ (ClassName?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (PrimitiveType?.GetHashCode() ?? 0); + public override int GetHashCode() { + unchecked { + int hashCode = this.ArrayDepth; + hashCode = (hashCode * 397) ^ (this.ClassName?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ (this.PrimitiveType?.GetHashCode() ?? 0); return hashCode; } } @@ -191,8 +175,7 @@ public override int GetHashCode() /// /// Primitive types enum /// - public enum PrimitiveType - { + public enum PrimitiveType { Boolean, Byte, Character, From 191520652d87c807c11d0e995761f9f2e85385ce Mon Sep 17 00:00:00 2001 From: REghZy Date: Fri, 22 Jul 2022 15:41:06 +0100 Subject: [PATCH 2/8] Added the ability to replace opcodes --- JavaAsm/Helpers/Extensions.cs | 6 ++ JavaAsm/Instructions/Instruction.cs | 2 +- .../Instructions/Types/FieldInstruction.cs | 23 ++++---- .../Types/IncrementInstruction.cs | 9 ++- .../Types/IntegerPushInstruction.cs | 22 ++++---- .../Types/InvokeDynamicInstruction.cs | 34 +++++------- JavaAsm/Instructions/Types/JumpInstruction.cs | 28 +++++----- JavaAsm/Instructions/Types/Label.cs | 21 +++---- JavaAsm/Instructions/Types/LdcInstruction.cs | 18 +++--- JavaAsm/Instructions/Types/LineNumber.cs | 18 +++--- .../Types/LookupSwitchInstruction.cs | 16 +++--- .../Instructions/Types/MethodInstruction.cs | 22 ++++---- .../Types/MultiANewArrayInstruction.cs | 18 +++--- .../Instructions/Types/NewArrayInstruction.cs | 9 ++- .../Instructions/Types/SimpleInstruction.cs | 55 ++++++++++--------- JavaAsm/Instructions/Types/StackMapFrame.cs | 40 ++++++-------- .../Types/TableSwitchInstruction.cs | 8 ++- JavaAsm/Instructions/Types/TypeInstruction.cs | 22 ++++---- .../Instructions/Types/VariableInstruction.cs | 24 ++++---- 19 files changed, 209 insertions(+), 186 deletions(-) diff --git a/JavaAsm/Helpers/Extensions.cs b/JavaAsm/Helpers/Extensions.cs index 4b3548b..d8258be 100644 --- a/JavaAsm/Helpers/Extensions.cs +++ b/JavaAsm/Helpers/Extensions.cs @@ -15,6 +15,12 @@ public static void CheckInAndThrow(this T value, string valueName, params T[] throw new ArgumentOutOfRangeException(nameof(valueName), $"{valueName} is not in [{string.Join(", ", values)}]"); } + public static T VerifyOpcode(this T value, string valueName, params T[] values) { + if (!values.Contains(value)) + throw new ArgumentOutOfRangeException(nameof(valueName), $"{valueName} is not in [{string.Join(", ", values)}]"); + return value; + } + public static bool TryAdd(this ICollection collection, T value) { if (collection.Contains(value)) return false; diff --git a/JavaAsm/Instructions/Instruction.cs b/JavaAsm/Instructions/Instruction.cs index b99f3ba..8b283fb 100644 --- a/JavaAsm/Instructions/Instruction.cs +++ b/JavaAsm/Instructions/Instruction.cs @@ -8,6 +8,6 @@ public abstract class Instruction public Instruction Next { get; internal set; } - public abstract Opcode Opcode { get; } + public abstract Opcode Opcode { get; set; } } } diff --git a/JavaAsm/Instructions/Types/FieldInstruction.cs b/JavaAsm/Instructions/Types/FieldInstruction.cs index 08d8e15..ad42e57 100644 --- a/JavaAsm/Instructions/Types/FieldInstruction.cs +++ b/JavaAsm/Instructions/Types/FieldInstruction.cs @@ -1,10 +1,13 @@ using JavaAsm.Helpers; -namespace JavaAsm.Instructions.Types -{ - public class FieldInstruction : Instruction - { - public override Opcode Opcode { get; } +namespace JavaAsm.Instructions.Types { + public class FieldInstruction : Instruction { + private Opcode opcode; + + public override Opcode Opcode { + get => this.opcode; + set => this.opcode = value.VerifyOpcode(nameof(value), Opcode.GETFIELD, Opcode.GETSTATIC, Opcode.PUTFIELD, Opcode.PUTSTATIC); + } public ClassName Owner { get; set; } @@ -12,16 +15,12 @@ public class FieldInstruction : Instruction public TypeDescriptor Descriptor { get; set; } - public FieldInstruction(Opcode opcode) - { - opcode.CheckInAndThrow(nameof(opcode), Opcode.GETFIELD, Opcode.GETSTATIC, Opcode.PUTFIELD, - Opcode.PUTSTATIC); + public FieldInstruction(Opcode opcode) { this.Opcode = opcode; } - public override string ToString() - { + public override string ToString() { return $"{this.Opcode} {this.Owner}.{this.Name} {this.Descriptor}"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/IncrementInstruction.cs b/JavaAsm/Instructions/Types/IncrementInstruction.cs index 20bcd6c..a6a3e03 100644 --- a/JavaAsm/Instructions/Types/IncrementInstruction.cs +++ b/JavaAsm/Instructions/Types/IncrementInstruction.cs @@ -1,8 +1,13 @@ -namespace JavaAsm.Instructions.Types +using System; + +namespace JavaAsm.Instructions.Types { public class IncrementInstruction : Instruction { - public override Opcode Opcode => Opcode.IINC; + public override Opcode Opcode { + get => Opcode.IINC; + set => throw new InvalidOperationException(GetType().Name + " only has 1 opcode"); + } public ushort VariableIndex { get; set; } diff --git a/JavaAsm/Instructions/Types/IntegerPushInstruction.cs b/JavaAsm/Instructions/Types/IntegerPushInstruction.cs index 7d6b158..39ebbfa 100644 --- a/JavaAsm/Instructions/Types/IntegerPushInstruction.cs +++ b/JavaAsm/Instructions/Types/IntegerPushInstruction.cs @@ -1,22 +1,22 @@ using JavaAsm.Helpers; -namespace JavaAsm.Instructions.Types -{ - public class IntegerPushInstruction : Instruction - { - public override Opcode Opcode { get; } +namespace JavaAsm.Instructions.Types { + public class IntegerPushInstruction : Instruction { + private Opcode opcode; + + public override Opcode Opcode { + get => this.opcode; + set => this.opcode = value.VerifyOpcode(nameof(value), Opcode.BIPUSH, Opcode.SIPUSH); + } public ushort Value { get; set; } - public IntegerPushInstruction(Opcode opcode) - { - opcode.CheckInAndThrow(nameof(opcode), Opcode.BIPUSH, Opcode.SIPUSH); + public IntegerPushInstruction(Opcode opcode) { this.Opcode = opcode; } - public override string ToString() - { + public override string ToString() { return $"{this.Opcode} {this.Value}"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/InvokeDynamicInstruction.cs b/JavaAsm/Instructions/Types/InvokeDynamicInstruction.cs index 1669c00..85e6ada 100644 --- a/JavaAsm/Instructions/Types/InvokeDynamicInstruction.cs +++ b/JavaAsm/Instructions/Types/InvokeDynamicInstruction.cs @@ -3,11 +3,12 @@ using JavaAsm.Helpers; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.Instructions.Types -{ - public class InvokeDynamicInstruction : Instruction - { - public override Opcode Opcode => Opcode.INVOKEDYNAMIC; +namespace JavaAsm.Instructions.Types { + public class InvokeDynamicInstruction : Instruction { + public override Opcode Opcode { + get => Opcode.INVOKEDYNAMIC; + set => throw new InvalidOperationException(GetType().Name + " only has 1 instruction"); + } public string Name { get; set; } @@ -18,8 +19,7 @@ public class InvokeDynamicInstruction : Instruction public List BootstrapMethodArgs { get; set; } } - public enum ReferenceKindType : byte - { + public enum ReferenceKindType : byte { GetField = 1, GetStatic, PutField, @@ -31,8 +31,7 @@ public enum ReferenceKindType : byte InvokeReference } - public class Handle - { + public class Handle { public ReferenceKindType Type { get; set; } public ClassName Owner { get; set; } @@ -41,23 +40,18 @@ public class Handle public IDescriptor Descriptor { get; set; } - internal static Handle FromConstantPool(MethodHandleEntry methodHandleEntry) - { - return new Handle - { + internal static Handle FromConstantPool(MethodHandleEntry methodHandleEntry) { + return new Handle { Type = methodHandleEntry.ReferenceKind, Descriptor = methodHandleEntry.ReferenceKind.IsFieldReference() - ? TypeDescriptor.Parse(methodHandleEntry.Reference.NameAndType - .Descriptor.String) - : (IDescriptor) MethodDescriptor.Parse(methodHandleEntry.Reference.NameAndType - .Descriptor.String), + ? TypeDescriptor.Parse(methodHandleEntry.Reference.NameAndType.Descriptor.String) + : (IDescriptor) MethodDescriptor.Parse(methodHandleEntry.Reference.NameAndType.Descriptor.String), Name = methodHandleEntry.Reference.NameAndType.Name.String, Owner = new ClassName(methodHandleEntry.Reference.Class.Name.String) }; } - internal MethodHandleEntry ToConstantPool() - { + internal MethodHandleEntry ToConstantPool() { ClassEntry referenceOwner = new ClassEntry(new Utf8Entry(this.Owner.Name)); NameAndTypeEntry referenceNameAndType = new NameAndTypeEntry(new Utf8Entry(this.Name), new Utf8Entry(this.Descriptor.ToString())); ReferenceEntry reference; @@ -85,4 +79,4 @@ internal MethodHandleEntry ToConstantPool() return new MethodHandleEntry(this.Type, reference); } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/JumpInstruction.cs b/JavaAsm/Instructions/Types/JumpInstruction.cs index 1a9d86a..bb5e320 100644 --- a/JavaAsm/Instructions/Types/JumpInstruction.cs +++ b/JavaAsm/Instructions/Types/JumpInstruction.cs @@ -1,24 +1,26 @@ using JavaAsm.Helpers; -namespace JavaAsm.Instructions.Types -{ - public class JumpInstruction : Instruction - { - public override Opcode Opcode { get; } +namespace JavaAsm.Instructions.Types { + public class JumpInstruction : Instruction { + private Opcode opcode; + + public override Opcode Opcode { + get => this.opcode; + set => this.opcode = value.VerifyOpcode(nameof(value), + Opcode.IFEQ, Opcode.IFNE, Opcode.IFLT, Opcode.IFGE, Opcode.IFGT, Opcode.IFLE, + Opcode.IF_ICMPEQ, Opcode.IF_ICMPNE, Opcode.IF_ICMPLT, Opcode.IF_ICMPGE, + Opcode.IF_ICMPGT, Opcode.IF_ICMPLE, Opcode.IF_ACMPEQ, Opcode.IF_ACMPNE, + Opcode.GOTO, Opcode.JSR, Opcode.IFNULL, Opcode.IFNONNULL); + } public Label Target { get; set; } - public JumpInstruction(Opcode opcode) - { - opcode.CheckInAndThrow(nameof(opcode), Opcode.IFEQ, Opcode.IFNE, Opcode.IFLT, Opcode.IFGE, Opcode.IFGT, - Opcode.IFLE, Opcode.IF_ICMPEQ, Opcode.IF_ICMPNE, Opcode.IF_ICMPLT, Opcode.IF_ICMPGE, Opcode.IF_ICMPGT, - Opcode.IF_ICMPLE, Opcode.IF_ACMPEQ, Opcode.IF_ACMPNE, Opcode.GOTO, Opcode.JSR, Opcode.IFNULL, Opcode.IFNONNULL); + public JumpInstruction(Opcode opcode) { this.Opcode = opcode; } - public override string ToString() - { + public override string ToString() { return $"{this.Opcode} L{this.Target.Index}"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/Label.cs b/JavaAsm/Instructions/Types/Label.cs index 0351990..f7b9a4c 100644 --- a/JavaAsm/Instructions/Types/Label.cs +++ b/JavaAsm/Instructions/Types/Label.cs @@ -1,21 +1,22 @@ -namespace JavaAsm.Instructions.Types -{ - public class Label : Instruction - { +using System; + +namespace JavaAsm.Instructions.Types { + public class Label : Instruction { private static long globalLabelIndex; public long Index { get; } - public override Opcode Opcode => Opcode.None; + public override Opcode Opcode { + get => Opcode.None; + set => throw new InvalidOperationException(GetType().Name + " does not have an instruction"); + } - public Label() - { + public Label() { this.Index = globalLabelIndex++; } - public override string ToString() - { + public override string ToString() { return $"LABEL L{this.Index}"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/LdcInstruction.cs b/JavaAsm/Instructions/Types/LdcInstruction.cs index 8fed518..299c9c3 100644 --- a/JavaAsm/Instructions/Types/LdcInstruction.cs +++ b/JavaAsm/Instructions/Types/LdcInstruction.cs @@ -1,17 +1,19 @@ -namespace JavaAsm.Instructions.Types -{ - public class LdcInstruction : Instruction - { - public override Opcode Opcode => Opcode.LDC; +using System; + +namespace JavaAsm.Instructions.Types { + public class LdcInstruction : Instruction { + public override Opcode Opcode { + get => Opcode.LDC; + set => throw new InvalidOperationException(GetType().Name + " only has 1 instruction"); + } public object Value { get; set; } - public override string ToString() - { + public override string ToString() { string stringValue = this.Value.ToString(); if (this.Value is string) stringValue = $"\"{stringValue}\""; return $"{this.Opcode} {stringValue}"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/LineNumber.cs b/JavaAsm/Instructions/Types/LineNumber.cs index 925eb42..ca5d35f 100644 --- a/JavaAsm/Instructions/Types/LineNumber.cs +++ b/JavaAsm/Instructions/Types/LineNumber.cs @@ -1,14 +1,16 @@ -namespace JavaAsm.Instructions.Types -{ - public class LineNumber : Instruction - { - public override Opcode Opcode => Opcode.None; +using System; + +namespace JavaAsm.Instructions.Types { + public class LineNumber : Instruction { + public override Opcode Opcode { + get => Opcode.None; + set => throw new InvalidOperationException(GetType().Name + " does not have an instruction"); + } public ushort Line { get; set; } - public override string ToString() - { + public override string ToString() { return $"LINE {this.Line}"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/LookupSwitchInstruction.cs b/JavaAsm/Instructions/Types/LookupSwitchInstruction.cs index f86b8f1..46a9022 100644 --- a/JavaAsm/Instructions/Types/LookupSwitchInstruction.cs +++ b/JavaAsm/Instructions/Types/LookupSwitchInstruction.cs @@ -1,13 +1,15 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; -namespace JavaAsm.Instructions.Types -{ - public class LookupSwitchInstruction : Instruction - { - public override Opcode Opcode => Opcode.LOOKUPSWITCH; +namespace JavaAsm.Instructions.Types { + public class LookupSwitchInstruction : Instruction { + public override Opcode Opcode { + get => Opcode.LOOKUPSWITCH; + set => throw new InvalidOperationException(GetType().Name + " only has 1 instruction"); + } public Label Default { get; set; } public List> MatchLabels { get; set; } = new List>(); } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/MethodInstruction.cs b/JavaAsm/Instructions/Types/MethodInstruction.cs index d79fc0d..5d50f6d 100644 --- a/JavaAsm/Instructions/Types/MethodInstruction.cs +++ b/JavaAsm/Instructions/Types/MethodInstruction.cs @@ -1,10 +1,13 @@ using JavaAsm.Helpers; -namespace JavaAsm.Instructions.Types -{ - public class MethodInstruction : Instruction - { - public override Opcode Opcode { get; } +namespace JavaAsm.Instructions.Types { + public class MethodInstruction : Instruction { + private Opcode opcode; + + public override Opcode Opcode { + get => this.opcode; + set => this.opcode = value.VerifyOpcode(nameof(value), Opcode.INVOKESTATIC, Opcode.INVOKEVIRTUAL, Opcode.INVOKEINTERFACE, Opcode.INVOKESPECIAL); + } public ClassName Owner { get; set; } @@ -12,14 +15,11 @@ public class MethodInstruction : Instruction public MethodDescriptor Descriptor { get; set; } - public MethodInstruction(Opcode opcode) - { - opcode.CheckInAndThrow(nameof(opcode), Opcode.INVOKESTATIC, Opcode.INVOKEVIRTUAL, Opcode.INVOKEINTERFACE, - Opcode.INVOKESPECIAL); + public MethodInstruction(Opcode opcode) { this.Opcode = opcode; } - public override string ToString() - { + + public override string ToString() { return $"{this.Opcode} {this.Owner}.{this.Name}{this.Descriptor}"; } } diff --git a/JavaAsm/Instructions/Types/MultiANewArrayInstruction.cs b/JavaAsm/Instructions/Types/MultiANewArrayInstruction.cs index 0fd2f6e..bd87d66 100644 --- a/JavaAsm/Instructions/Types/MultiANewArrayInstruction.cs +++ b/JavaAsm/Instructions/Types/MultiANewArrayInstruction.cs @@ -1,16 +1,18 @@ -namespace JavaAsm.Instructions.Types -{ - public class MultiANewArrayInstruction : Instruction - { - public override Opcode Opcode => Opcode.MULTIANEWARRAY; +using System; + +namespace JavaAsm.Instructions.Types { + public class MultiANewArrayInstruction : Instruction { + public override Opcode Opcode { + get => Opcode.MULTIANEWARRAY; + set => throw new InvalidOperationException(GetType().Name + " only has 1 instruction"); + } public ClassName Type { get; set; } public byte Dimensions { get; set; } - public override string ToString() - { + public override string ToString() { return $"{this.Opcode} {this.Type} {this.Dimensions}"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/NewArrayInstruction.cs b/JavaAsm/Instructions/Types/NewArrayInstruction.cs index 8975449..0d252e5 100644 --- a/JavaAsm/Instructions/Types/NewArrayInstruction.cs +++ b/JavaAsm/Instructions/Types/NewArrayInstruction.cs @@ -1,8 +1,13 @@ -namespace JavaAsm.Instructions.Types +using System; + +namespace JavaAsm.Instructions.Types { public class NewArrayInstruction : Instruction { - public override Opcode Opcode => Opcode.NEWARRAY; + public override Opcode Opcode { + get => Opcode.NEWARRAY; + set => throw new InvalidOperationException(GetType().Name + " only has 1 instruction"); + } public NewArrayTypeCode ArrayType { get; set; } diff --git a/JavaAsm/Instructions/Types/SimpleInstruction.cs b/JavaAsm/Instructions/Types/SimpleInstruction.cs index 1cd3da4..788a243 100644 --- a/JavaAsm/Instructions/Types/SimpleInstruction.cs +++ b/JavaAsm/Instructions/Types/SimpleInstruction.cs @@ -1,35 +1,38 @@ using JavaAsm.Helpers; -namespace JavaAsm.Instructions.Types -{ - public class SimpleInstruction : Instruction - { - public override Opcode Opcode { get; } +namespace JavaAsm.Instructions.Types { + public class SimpleInstruction : Instruction { + private static readonly Opcode[] ValidOpcodes = { + Opcode.NOP, Opcode.ACONST_NULL, Opcode.ICONST_M1, Opcode.ICONST_0, Opcode.ICONST_1, Opcode.ICONST_2, + Opcode.ICONST_3, Opcode.ICONST_4, Opcode.ICONST_5, Opcode.LCONST_0, Opcode.LCONST_1, Opcode.FCONST_0, + Opcode.FCONST_1, Opcode.FCONST_2, Opcode.DCONST_0, Opcode.DCONST_1, Opcode.IALOAD, Opcode.LALOAD, Opcode.FALOAD, + Opcode.DALOAD, Opcode.AALOAD, Opcode.BALOAD, Opcode.CALOAD, Opcode.SALOAD, Opcode.IASTORE, Opcode.LASTORE, + Opcode.FASTORE, Opcode.DASTORE, Opcode.AASTORE, Opcode.BASTORE, Opcode.CASTORE, Opcode.SASTORE, Opcode.POP, + Opcode.POP2, Opcode.DUP, Opcode.DUP_X1, Opcode.DUP_X2, Opcode.DUP2, Opcode.DUP2_X1, Opcode.DUP2_X2, Opcode.SWAP, + Opcode.IADD, Opcode.LADD, Opcode.FADD, Opcode.DADD, Opcode.ISUB, Opcode.LSUB, Opcode.FSUB, Opcode.DSUB, + Opcode.IMUL, Opcode.LMUL, Opcode.FMUL, Opcode.DMUL, Opcode.IDIV, Opcode.LDIV, Opcode.FDIV, Opcode.DDIV, + Opcode.IREM, Opcode.LREM, Opcode.FREM, Opcode.DREM, Opcode.INEG, Opcode.LNEG, Opcode.FNEG, Opcode.DNEG, + Opcode.ISHL, Opcode.LSHL, Opcode.ISHR, Opcode.LSHR, Opcode.IUSHR, Opcode.LUSHR, Opcode.IAND, Opcode.LAND, + Opcode.IOR, Opcode.LOR, Opcode.IXOR, Opcode.LXOR, Opcode.I2L, Opcode.I2F, Opcode.I2D, Opcode.L2I, Opcode.L2F, + Opcode.L2D, Opcode.F2I, Opcode.F2L, Opcode.F2D, Opcode.D2I, Opcode.D2L, Opcode.D2F, Opcode.I2B, Opcode.I2C, + Opcode.I2S, Opcode.LCMP, Opcode.FCMPL, Opcode.FCMPG, Opcode.DCMPL, Opcode.DCMPG, Opcode.IRETURN, Opcode.LRETURN, + Opcode.FRETURN, Opcode.DRETURN, Opcode.ARETURN, Opcode.RETURN, Opcode.ARRAYLENGTH, Opcode.ATHROW, + Opcode.MONITORENTER, Opcode.MONITOREXIT + }; - public SimpleInstruction(Opcode opcode) - { - opcode.CheckInAndThrow(nameof(opcode), - Opcode.NOP, Opcode.ACONST_NULL, Opcode.ICONST_M1, Opcode.ICONST_0, Opcode.ICONST_1, Opcode.ICONST_2, - Opcode.ICONST_3, Opcode.ICONST_4, Opcode.ICONST_5, Opcode.LCONST_0, Opcode.LCONST_1, Opcode.FCONST_0, - Opcode.FCONST_1, Opcode.FCONST_2, Opcode.DCONST_0, Opcode.DCONST_1, Opcode.IALOAD, Opcode.LALOAD, Opcode.FALOAD, - Opcode.DALOAD, Opcode.AALOAD, Opcode.BALOAD, Opcode.CALOAD, Opcode.SALOAD, Opcode.IASTORE, Opcode.LASTORE, - Opcode.FASTORE, Opcode.DASTORE, Opcode.AASTORE, Opcode.BASTORE, Opcode.CASTORE, Opcode.SASTORE, Opcode.POP, - Opcode.POP2, Opcode.DUP, Opcode.DUP_X1, Opcode.DUP_X2, Opcode.DUP2, Opcode.DUP2_X1, Opcode.DUP2_X2, Opcode.SWAP, - Opcode.IADD, Opcode.LADD, Opcode.FADD, Opcode.DADD, Opcode.ISUB, Opcode.LSUB, Opcode.FSUB, Opcode.DSUB, - Opcode.IMUL, Opcode.LMUL, Opcode.FMUL, Opcode.DMUL, Opcode.IDIV, Opcode.LDIV, Opcode.FDIV, Opcode.DDIV, - Opcode.IREM, Opcode.LREM, Opcode.FREM, Opcode.DREM, Opcode.INEG, Opcode.LNEG, Opcode.FNEG, Opcode.DNEG, - Opcode.ISHL, Opcode.LSHL, Opcode.ISHR, Opcode.LSHR, Opcode.IUSHR, Opcode.LUSHR, Opcode.IAND, Opcode.LAND, - Opcode.IOR, Opcode.LOR, Opcode.IXOR, Opcode.LXOR, Opcode.I2L, Opcode.I2F, Opcode.I2D, Opcode.L2I, Opcode.L2F, - Opcode.L2D, Opcode.F2I, Opcode.F2L, Opcode.F2D, Opcode.D2I, Opcode.D2L, Opcode.D2F, Opcode.I2B, Opcode.I2C, - Opcode.I2S, Opcode.LCMP, Opcode.FCMPL, Opcode.FCMPG, Opcode.DCMPL, Opcode.DCMPG, Opcode.IRETURN, Opcode.LRETURN, - Opcode.FRETURN, Opcode.DRETURN, Opcode.ARETURN, Opcode.RETURN, Opcode.ARRAYLENGTH, Opcode.ATHROW, - Opcode.MONITORENTER, Opcode.MONITOREXIT); + private Opcode opcode; + + public override Opcode Opcode { + get => this.opcode; + set => this.opcode = value.VerifyOpcode(nameof(value), ValidOpcodes); + } + + public SimpleInstruction(Opcode opcode) { this.Opcode = opcode; } - public override string ToString() - { + public override string ToString() { return $"{this.Opcode}"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/StackMapFrame.cs b/JavaAsm/Instructions/Types/StackMapFrame.cs index 8a0641b..3039f77 100644 --- a/JavaAsm/Instructions/Types/StackMapFrame.cs +++ b/JavaAsm/Instructions/Types/StackMapFrame.cs @@ -1,10 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using JavaAsm.Helpers; -namespace JavaAsm.Instructions.Types -{ - public enum VerificationElementType - { +namespace JavaAsm.Instructions.Types { + public enum VerificationElementType { Top, Integer, Float, @@ -16,39 +15,33 @@ public enum VerificationElementType Unitialized } - public abstract class VerificationElement - { + public abstract class VerificationElement { public abstract VerificationElementType Type { get; } } - public class SimpleVerificationElement : VerificationElement - { + public class SimpleVerificationElement : VerificationElement { public override VerificationElementType Type { get; } - public SimpleVerificationElement(VerificationElementType type) - { + public SimpleVerificationElement(VerificationElementType type) { type.CheckInAndThrow(nameof(type), VerificationElementType.Top, VerificationElementType.Integer, VerificationElementType.Float, VerificationElementType.Long, VerificationElementType.Double, VerificationElementType.Null, VerificationElementType.UnitializedThis); this.Type = type; } } - public class ObjectVerificationElement : VerificationElement - { + public class ObjectVerificationElement : VerificationElement { public override VerificationElementType Type => VerificationElementType.Object; public ClassName ObjectClass { get; set; } } - public class UninitializedVerificationElement : VerificationElement - { + public class UninitializedVerificationElement : VerificationElement { public override VerificationElementType Type => VerificationElementType.Unitialized; public TypeInstruction NewInstruction { get; set; } } - public enum FrameType - { + public enum FrameType { Same, SameLocals1StackItem, Chop, @@ -56,9 +49,11 @@ public enum FrameType Full } - public class StackMapFrame : Instruction - { - public override Opcode Opcode => Opcode.None; + public class StackMapFrame : Instruction { + public override Opcode Opcode { + get => Opcode.None; + set => throw new InvalidOperationException(GetType().Name + " does not have an instruction"); + } public FrameType Type { get; set; } @@ -68,9 +63,8 @@ public class StackMapFrame : Instruction public byte? ChopK { get; set; } - public override string ToString() - { + public override string ToString() { return "STACKFRAME"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/TableSwitchInstruction.cs b/JavaAsm/Instructions/Types/TableSwitchInstruction.cs index 1cf4ac8..f1ca275 100644 --- a/JavaAsm/Instructions/Types/TableSwitchInstruction.cs +++ b/JavaAsm/Instructions/Types/TableSwitchInstruction.cs @@ -1,10 +1,14 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace JavaAsm.Instructions.Types { public class TableSwitchInstruction : Instruction { - public override Opcode Opcode => Opcode.TABLESWITCH; + public override Opcode Opcode { + get => Opcode.TABLESWITCH; + set => throw new InvalidOperationException(GetType().Name + " only has 1 opcode"); + } public Label Default { get; set; } diff --git a/JavaAsm/Instructions/Types/TypeInstruction.cs b/JavaAsm/Instructions/Types/TypeInstruction.cs index 83cf5d4..8266c99 100644 --- a/JavaAsm/Instructions/Types/TypeInstruction.cs +++ b/JavaAsm/Instructions/Types/TypeInstruction.cs @@ -1,22 +1,22 @@ using JavaAsm.Helpers; -namespace JavaAsm.Instructions.Types -{ - public class TypeInstruction : Instruction - { - public override Opcode Opcode { get; } +namespace JavaAsm.Instructions.Types { + public class TypeInstruction : Instruction { + private Opcode opcode; + + public override Opcode Opcode { + get => this.opcode; + set => this.opcode = value.VerifyOpcode(nameof(value), Opcode.NEW, Opcode.ANEWARRAY, Opcode.CHECKCAST, Opcode.INSTANCEOF); + } public ClassName Type { get; set; } - public TypeInstruction(Opcode opcode) - { - opcode.CheckInAndThrow(nameof(opcode), Opcode.NEW, Opcode.ANEWARRAY, Opcode.CHECKCAST, Opcode.INSTANCEOF); + public TypeInstruction(Opcode opcode) { this.Opcode = opcode; } - public override string ToString() - { + public override string ToString() { return $"{this.Opcode} {this.Type}"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/VariableInstruction.cs b/JavaAsm/Instructions/Types/VariableInstruction.cs index 3ec6f56..8b929be 100644 --- a/JavaAsm/Instructions/Types/VariableInstruction.cs +++ b/JavaAsm/Instructions/Types/VariableInstruction.cs @@ -1,22 +1,24 @@ using JavaAsm.Helpers; -namespace JavaAsm.Instructions.Types -{ - public class VariableInstruction : Instruction - { - public override Opcode Opcode { get; } +namespace JavaAsm.Instructions.Types { + public class VariableInstruction : Instruction { + private Opcode opcode; + + public override Opcode Opcode { + get => this.opcode; + set => this.opcode = value.VerifyOpcode(nameof(value), + Opcode.ILOAD, Opcode.LLOAD, Opcode.FLOAD, Opcode.DLOAD, + Opcode.ALOAD, Opcode.ISTORE, Opcode.LSTORE, Opcode.FSTORE, + Opcode.DSTORE, Opcode.ASTORE, Opcode.RET); + } public ushort VariableIndex { get; set; } - public VariableInstruction(Opcode opcode) - { - opcode.CheckInAndThrow(nameof(opcode), Opcode.ILOAD, Opcode.LLOAD, Opcode.FLOAD, Opcode.DLOAD, Opcode.ALOAD, - Opcode.ISTORE, Opcode.LSTORE, Opcode.FSTORE, Opcode.DSTORE, Opcode.ASTORE, Opcode.RET); + public VariableInstruction(Opcode opcode) { this.Opcode = opcode; } - public override string ToString() - { + public override string ToString() { return $"{this.Opcode} {this.VariableIndex}"; } } From 8ae79508a8946e136c6e1cd6c64cde912d51af6b Mon Sep 17 00:00:00 2001 From: REghZy Date: Sat, 23 Jul 2022 18:32:56 +0100 Subject: [PATCH 3/8] Stopped InnerClass attribute being saved if there are no inner classes (can cause jd-core decompiler to crash) --- JavaAsm/ClassNode.cs | 84 +++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 56 deletions(-) diff --git a/JavaAsm/ClassNode.cs b/JavaAsm/ClassNode.cs index 55f041d..8e494f9 100644 --- a/JavaAsm/ClassNode.cs +++ b/JavaAsm/ClassNode.cs @@ -5,13 +5,11 @@ using JavaAsm.CustomAttributes.Annotation; using JavaAsm.IO; -namespace JavaAsm -{ +namespace JavaAsm { /// /// Class node /// - public class ClassNode - { + public class ClassNode { public ClassVersion MajorVersion { get; set; } public ushort MinorVersion { get; set; } @@ -47,16 +45,14 @@ public class ClassNode public List InnerClasses { get; set; } = new List(); - private AttributeNode GetAttribute(string name) - { + private AttributeNode GetAttribute(string name) { AttributeNode attribute = this.Attributes.FirstOrDefault(a => a.Name == name); if (attribute != null) this.Attributes.Remove(attribute); return attribute; } - internal void Parse(ClassReaderState readerState) - { + internal void Parse(ClassReaderState readerState) { this.SourceFile = (GetAttribute(PredefinedAttributeNames.SourceFile)?.ParsedAttribute as SourceFileAttribute)?.Value; this.SourceDebugExtension = (GetAttribute(PredefinedAttributeNames.SourceDebugExtension)?.ParsedAttribute as SourceFileAttribute)?.Value; this.Signature = (GetAttribute(PredefinedAttributeNames.Signature)?.ParsedAttribute as SignatureAttribute)?.Value; @@ -85,117 +81,94 @@ internal void Parse(ClassReaderState readerState) field.Parse(readerState); } - internal void Save(ClassWriterState writerState) - { - if (this.SourceFile != null) - { + internal void Save(ClassWriterState writerState) { + if (this.SourceFile != null) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.SourceFile)) throw new Exception( $"{PredefinedAttributeNames.SourceFile} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.SourceFile, - ParsedAttribute = new SourceFileAttribute - { + ParsedAttribute = new SourceFileAttribute { Value = this.SourceFile } }); } - if (this.SourceDebugExtension != null) - { + if (this.SourceDebugExtension != null) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.SourceDebugExtension)) throw new Exception( $"{PredefinedAttributeNames.SourceDebugExtension} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.SourceDebugExtension, - ParsedAttribute = new SourceDebugExtensionAttribute - { + ParsedAttribute = new SourceDebugExtensionAttribute { Value = this.SourceDebugExtension } }); } - if (this.Signature != null) - { + if (this.Signature != null) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Signature)) throw new Exception( $"{PredefinedAttributeNames.Signature} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Signature, - ParsedAttribute = new SignatureAttribute - { + ParsedAttribute = new SignatureAttribute { Value = this.Signature } }); } - if (this.InvisibleAnnotations != null && this.InvisibleAnnotations.Count > 0) - { + if (this.InvisibleAnnotations != null && this.InvisibleAnnotations.Count > 0) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeInvisibleAnnotations)) throw new Exception( $"{PredefinedAttributeNames.RuntimeInvisibleAnnotations} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeInvisibleAnnotations, - ParsedAttribute = new RuntimeInvisibleAnnotationsAttribute - { + ParsedAttribute = new RuntimeInvisibleAnnotationsAttribute { Annotations = this.InvisibleAnnotations } }); } - if (this.VisibleAnnotations != null && this.VisibleAnnotations.Count > 0) - { + if (this.VisibleAnnotations != null && this.VisibleAnnotations.Count > 0) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeVisibleAnnotations)) throw new Exception( $"{PredefinedAttributeNames.RuntimeVisibleAnnotations} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeVisibleAnnotations, - ParsedAttribute = new RuntimeVisibleAnnotationsAttribute - { + ParsedAttribute = new RuntimeVisibleAnnotationsAttribute { Annotations = this.VisibleAnnotations } }); } - if (this.IsDeprecated) - { + if (this.IsDeprecated) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Deprecated)) throw new Exception( $"{PredefinedAttributeNames.Deprecated} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Deprecated, ParsedAttribute = new DeprecatedAttribute() }); } - if (this.EnclosingMethod != null) - { + if (this.EnclosingMethod != null) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.EnclosingMethod)) throw new Exception( $"{PredefinedAttributeNames.EnclosingMethod} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.EnclosingMethod, ParsedAttribute = this.EnclosingMethod }); } - if (this.InnerClasses != null) - { + if (this.InnerClasses != null && this.InnerClasses.Count > 0) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.InnerClasses)) throw new Exception( $"{PredefinedAttributeNames.InnerClasses} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.InnerClasses, - ParsedAttribute = new InnerClassesAttribute - { + ParsedAttribute = new InnerClassesAttribute { Classes = this.InnerClasses } }); @@ -208,8 +181,7 @@ internal void Save(ClassWriterState writerState) field.Save(writerState); } - public override string ToString() - { + public override string ToString() { return $"{AccessModifiersExtensions.ToString(this.Access)} {this.Name}"; } } From 7fcd58e0bcb7eba60054c0f2990617f6af6e318e Mon Sep 17 00:00:00 2001 From: REghZy Date: Sat, 23 Jul 2022 20:58:39 +0100 Subject: [PATCH 4/8] Added support for local variable names (also reformatted code a bit) --- JavaAsm/AttributeNode.cs | 111 +++--- JavaAsm/ClassAccessModifiers.cs | 1 - JavaAsm/ClassName.cs | 27 +- JavaAsm/ClassNode.cs | 24 +- JavaAsm/ClassVersion.cs | 6 +- .../Annotation/AnnotationNode.cs | 32 +- .../Annotation/ElementValue.cs | 47 +-- .../AnnotationDefaultAttribute.cs | 20 +- .../BootstrapMethodsAttribute.cs | 47 +-- JavaAsm/CustomAttributes/CodeAttribute.cs | 42 +-- .../ConstantValueAttribute.cs | 54 ++- .../CustomAttributes/DeprecatedAttribute.cs | 9 +- .../EnclosingMethodAttribute.cs | 29 +- .../CustomAttributes/ExceptionsAttribute.cs | 20 +- .../CustomAttributes/InnerClassesAttribute.cs | 47 +-- .../LineNumberTableAttribute.cs | 26 +- .../LocalVariableTableAttribute.cs | 26 +- .../LocalVariableTypeTableAttribute.cs | 26 +- .../MethodParametersAttribute.cs | 26 +- .../RuntimeInvisibleAnnotationsAttribute.cs | 18 +- ...eInvisibleParameterAnnotationsAttribute.cs | 29 +- ...untimeInvisibleTypeAnnotationsAttribute.cs | 17 +- .../RuntimeVisibleAnnotationsAttribute.cs | 17 +- ...imeVisibleParameterAnnotationsAttribute.cs | 23 +- .../RuntimeVisibleTypeAnnotationsAttribute.cs | 17 +- .../CustomAttributes/SignatureAttribute.cs | 20 +- .../SourceDebugExtensionAttribute.cs | 20 +- .../CustomAttributes/SourceFileAttribute.cs | 20 +- .../StackMapTableAttribute.cs | 117 ++---- .../CustomAttributes/SyntheticAttribute.cs | 11 +- .../TypeAnnotation/CatchTarget.cs | 12 +- .../TypeAnnotation/EmptyTarget.cs | 6 +- .../TypeAnnotation/FormalParameterTarget.cs | 12 +- .../TypeAnnotation/LocalvarTarget.cs | 24 +- .../TypeAnnotation/OffsetTarget.cs | 12 +- .../TypeAnnotation/SupertypeTarget.cs | 12 +- .../TypeAnnotation/TargetType.cs | 6 +- .../TypeAnnotation/TargetTypeKind.cs | 6 +- .../TypeAnnotation/ThrowsTarget.cs | 12 +- .../TypeAnnotation/TypeAnnotationNode.cs | 35 +- .../TypeAnnotation/TypeAnnotationTarget.cs | 6 +- .../TypeAnnotation/TypeArgumentTarget.cs | 12 +- .../TypeParameterBoundTarget.cs | 12 +- .../TypeAnnotation/TypeParameterTarget.cs | 12 +- .../TypeAnnotation/TypePath.cs | 27 +- JavaAsm/FieldNode.cs | 75 ++-- JavaAsm/Helpers/ModifiedUtf8Helper.cs | 59 ++- JavaAsm/Helpers/ReadCountStream.cs | 23 +- JavaAsm/IDescriptor.cs | 6 +- JavaAsm/IO/ClassFile.cs | 54 +-- JavaAsm/IO/ClassReaderState.cs | 6 +- JavaAsm/IO/ClassWriterState.cs | 6 +- JavaAsm/IO/ConstantPool.cs | 56 ++- JavaAsm/IO/ConstantPoolEntries/ClassEntry.cs | 38 +- JavaAsm/IO/ConstantPoolEntries/DoubleEntry.cs | 32 +- JavaAsm/IO/ConstantPoolEntries/Entry.cs | 8 +- JavaAsm/IO/ConstantPoolEntries/EntryTag.cs | 6 +- .../FieldReferenceEntry.cs | 6 +- .../IO/ConstantPoolEntries/IntegerEntry.cs | 32 +- .../InterfaceMethodReferenceEntry.cs | 6 +- .../ConstantPoolEntries/InvokeDynamicEntry.cs | 41 +- JavaAsm/IO/ConstantPoolEntries/LongEntry.cs | 32 +- .../ConstantPoolEntries/MethodHandleEntry.cs | 54 ++- .../MethodReferenceEntry.cs | 6 +- .../IO/ConstantPoolEntries/MethodTypeEntry.cs | 38 +- .../ConstantPoolEntries/NameAndTypeEntry.cs | 41 +- .../IO/ConstantPoolEntries/ReferenceEntry.cs | 41 +- JavaAsm/IO/ConstantPoolEntries/StringEntry.cs | 38 +- JavaAsm/IO/ConstantPoolEntries/Utf8Entry.cs | 32 +- JavaAsm/Instructions/Instruction.cs | 8 +- JavaAsm/Instructions/InstructionList.cs | 42 +-- .../Instructions/InstructionListConverter.cs | 353 +++++++++--------- JavaAsm/Instructions/Opcode.cs | 8 +- .../Types/IncrementInstruction.cs | 11 +- .../Instructions/Types/NewArrayInstruction.cs | 14 +- .../Types/TableSwitchInstruction.cs | 8 +- .../Instructions/Types/VariableInstruction.cs | 2 +- JavaAsm/MethodDescriptor.cs | 33 +- JavaAsm/MethodNode.cs | 98 ++--- JavaAsm/TryCatchNode.cs | 6 +- JavaAsm/TypeDescriptor.cs | 36 +- JavaAsmTests/UnitTest1.cs | 9 +- 82 files changed, 1020 insertions(+), 1479 deletions(-) diff --git a/JavaAsm/AttributeNode.cs b/JavaAsm/AttributeNode.cs index bb71818..16ac9ec 100644 --- a/JavaAsm/AttributeNode.cs +++ b/JavaAsm/AttributeNode.cs @@ -6,10 +6,8 @@ using JavaAsm.Helpers; using JavaAsm.IO; -namespace JavaAsm -{ - public static class PredefinedAttributeNames - { +namespace JavaAsm { + public static class PredefinedAttributeNames { public const string AnnotationDefault = "AnnotationDefault"; public const string BootstrapMethods = "BootstrapMethods"; public const string Code = "Code"; @@ -35,50 +33,48 @@ public static class PredefinedAttributeNames public const string Synthetic = "Synthetic"; } - public class AttributeNode - { + public class AttributeNode { private static readonly Dictionary<(string Name, AttributeScope Scope), ICustomAttributeFactory> predefinedAttributes - = new Dictionary<(string Name, AttributeScope Scope), ICustomAttributeFactory> - { - { (PredefinedAttributeNames.Code, AttributeScope.Method), new CodeAttributeFactory() }, - { (PredefinedAttributeNames.ConstantValue, AttributeScope.Field), new ConstantValueAttributeFactory() }, - { (PredefinedAttributeNames.SourceDebugExtension, AttributeScope.Class), new SourceDebugExtensionFactory() }, - { (PredefinedAttributeNames.SourceFile, AttributeScope.Class), new SourceFileAttributeFactory() }, - { (PredefinedAttributeNames.Exceptions, AttributeScope.Method), new ExceptionsAttributeFactory() }, - { (PredefinedAttributeNames.EnclosingMethod, AttributeScope.Class), new EnclosingMethodAttributeFactory() }, - { (PredefinedAttributeNames.Synthetic, AttributeScope.Class), new SyntheticAttributeFactory() }, - { (PredefinedAttributeNames.Synthetic, AttributeScope.Method), new SyntheticAttributeFactory() }, - { (PredefinedAttributeNames.Synthetic, AttributeScope.Field), new SyntheticAttributeFactory() }, - { (PredefinedAttributeNames.Signature, AttributeScope.Class), new SignatureAttributeFactory() }, - { (PredefinedAttributeNames.Signature, AttributeScope.Method), new SignatureAttributeFactory() }, - { (PredefinedAttributeNames.Signature, AttributeScope.Field), new SignatureAttributeFactory() }, - { (PredefinedAttributeNames.LineNumberTable, AttributeScope.Code), new LineNumberTableAttributeFactory() }, - { (PredefinedAttributeNames.Deprecated, AttributeScope.Class), new DeprecatedAttributeFactory() }, - { (PredefinedAttributeNames.Deprecated, AttributeScope.Method), new DeprecatedAttributeFactory() }, - { (PredefinedAttributeNames.Deprecated, AttributeScope.Field), new DeprecatedAttributeFactory() }, - { (PredefinedAttributeNames.MethodParameters, AttributeScope.Method), new MethodParametersAttributeFactory() }, - { (PredefinedAttributeNames.LocalVariableTable, AttributeScope.Code), new LocalVariableTableAttributeFactory() }, - { (PredefinedAttributeNames.LocalVariableTypeTable, AttributeScope.Code), new LocalVariableTypeTableAttributeFactory() }, - { (PredefinedAttributeNames.InnerClasses, AttributeScope.Class), new InnerClassesAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeInvisibleAnnotations, AttributeScope.Class), new RuntimeInvisibleAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeInvisibleAnnotations, AttributeScope.Method), new RuntimeInvisibleAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeInvisibleAnnotations, AttributeScope.Field), new RuntimeInvisibleAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeVisibleAnnotations, AttributeScope.Class), new RuntimeVisibleAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeVisibleAnnotations, AttributeScope.Method), new RuntimeVisibleAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeVisibleAnnotations, AttributeScope.Field), new RuntimeVisibleAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeInvisibleParameterAnnotations, AttributeScope.Method), new RuntimeInvisibleParameterAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeVisibleParameterAnnotations, AttributeScope.Method), new RuntimeVisibleParameterAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeInvisibleTypeAnnotations, AttributeScope.Class), new RuntimeInvisibleTypeAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeInvisibleTypeAnnotations, AttributeScope.Method), new RuntimeInvisibleTypeAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeInvisibleTypeAnnotations, AttributeScope.Field), new RuntimeInvisibleTypeAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeInvisibleTypeAnnotations, AttributeScope.Code), new RuntimeInvisibleTypeAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeVisibleTypeAnnotations, AttributeScope.Class), new RuntimeVisibleTypeAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeVisibleTypeAnnotations, AttributeScope.Method), new RuntimeVisibleTypeAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeVisibleTypeAnnotations, AttributeScope.Field), new RuntimeVisibleTypeAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.RuntimeVisibleTypeAnnotations, AttributeScope.Code), new RuntimeVisibleTypeAnnotationsAttributeFactory() }, - { (PredefinedAttributeNames.AnnotationDefault, AttributeScope.Method), new AnnotationDefaultAttributeFactory() }, - { (PredefinedAttributeNames.BootstrapMethods, AttributeScope.Class), new BootstrapMethodsAttributeFactory() }, - { (PredefinedAttributeNames.StackMapTable, AttributeScope.Code), new StackMapTableAttributeFactory() } + = new Dictionary<(string Name, AttributeScope Scope), ICustomAttributeFactory> { + {(PredefinedAttributeNames.Code, AttributeScope.Method), new CodeAttributeFactory()}, + {(PredefinedAttributeNames.ConstantValue, AttributeScope.Field), new ConstantValueAttributeFactory()}, + {(PredefinedAttributeNames.SourceDebugExtension, AttributeScope.Class), new SourceDebugExtensionFactory()}, + {(PredefinedAttributeNames.SourceFile, AttributeScope.Class), new SourceFileAttributeFactory()}, + {(PredefinedAttributeNames.Exceptions, AttributeScope.Method), new ExceptionsAttributeFactory()}, + {(PredefinedAttributeNames.EnclosingMethod, AttributeScope.Class), new EnclosingMethodAttributeFactory()}, + {(PredefinedAttributeNames.Synthetic, AttributeScope.Class), new SyntheticAttributeFactory()}, + {(PredefinedAttributeNames.Synthetic, AttributeScope.Method), new SyntheticAttributeFactory()}, + {(PredefinedAttributeNames.Synthetic, AttributeScope.Field), new SyntheticAttributeFactory()}, + {(PredefinedAttributeNames.Signature, AttributeScope.Class), new SignatureAttributeFactory()}, + {(PredefinedAttributeNames.Signature, AttributeScope.Method), new SignatureAttributeFactory()}, + {(PredefinedAttributeNames.Signature, AttributeScope.Field), new SignatureAttributeFactory()}, + {(PredefinedAttributeNames.LineNumberTable, AttributeScope.Code), new LineNumberTableAttributeFactory()}, + {(PredefinedAttributeNames.Deprecated, AttributeScope.Class), new DeprecatedAttributeFactory()}, + {(PredefinedAttributeNames.Deprecated, AttributeScope.Method), new DeprecatedAttributeFactory()}, + {(PredefinedAttributeNames.Deprecated, AttributeScope.Field), new DeprecatedAttributeFactory()}, + {(PredefinedAttributeNames.MethodParameters, AttributeScope.Method), new MethodParametersAttributeFactory()}, + {(PredefinedAttributeNames.LocalVariableTable, AttributeScope.Code), new LocalVariableTableAttributeFactory()}, + {(PredefinedAttributeNames.LocalVariableTypeTable, AttributeScope.Code), new LocalVariableTypeTableAttributeFactory()}, + {(PredefinedAttributeNames.InnerClasses, AttributeScope.Class), new InnerClassesAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeInvisibleAnnotations, AttributeScope.Class), new RuntimeInvisibleAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeInvisibleAnnotations, AttributeScope.Method), new RuntimeInvisibleAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeInvisibleAnnotations, AttributeScope.Field), new RuntimeInvisibleAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeVisibleAnnotations, AttributeScope.Class), new RuntimeVisibleAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeVisibleAnnotations, AttributeScope.Method), new RuntimeVisibleAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeVisibleAnnotations, AttributeScope.Field), new RuntimeVisibleAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeInvisibleParameterAnnotations, AttributeScope.Method), new RuntimeInvisibleParameterAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeVisibleParameterAnnotations, AttributeScope.Method), new RuntimeVisibleParameterAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeInvisibleTypeAnnotations, AttributeScope.Class), new RuntimeInvisibleTypeAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeInvisibleTypeAnnotations, AttributeScope.Method), new RuntimeInvisibleTypeAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeInvisibleTypeAnnotations, AttributeScope.Field), new RuntimeInvisibleTypeAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeInvisibleTypeAnnotations, AttributeScope.Code), new RuntimeInvisibleTypeAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeVisibleTypeAnnotations, AttributeScope.Class), new RuntimeVisibleTypeAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeVisibleTypeAnnotations, AttributeScope.Method), new RuntimeVisibleTypeAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeVisibleTypeAnnotations, AttributeScope.Field), new RuntimeVisibleTypeAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.RuntimeVisibleTypeAnnotations, AttributeScope.Code), new RuntimeVisibleTypeAnnotationsAttributeFactory()}, + {(PredefinedAttributeNames.AnnotationDefault, AttributeScope.Method), new AnnotationDefaultAttributeFactory()}, + {(PredefinedAttributeNames.BootstrapMethods, AttributeScope.Class), new BootstrapMethodsAttributeFactory()}, + {(PredefinedAttributeNames.StackMapTable, AttributeScope.Code), new StackMapTableAttributeFactory()} }; public string Name { get; set; } @@ -87,13 +83,11 @@ public class AttributeNode public CustomAttribute ParsedAttribute { get; set; } - internal void Parse(Stream stream, AttributeScope scope, ClassReaderState readerState) - { + internal void Parse(Stream stream, AttributeScope scope, ClassReaderState readerState) { uint dataLength = Binary.BigEndian.ReadUInt32(stream); byte[] data = stream.ReadBytes(dataLength); - try - { + try { if (!predefinedAttributes.ContainsKey((this.Name, scope))) throw new ArgumentException($"Attribute {this.Name} in {scope} not found"); ReadWriteCountStream readWriteCounter = new ReadWriteCountStream(new MemoryStream(data)); @@ -101,27 +95,22 @@ internal void Parse(Stream stream, AttributeScope scope, ClassReaderState reader if (readWriteCounter.ReadBytes != dataLength) throw new ArgumentOutOfRangeException(nameof(dataLength), $"Wrong data length of attribute {this.Name} in {scope}: Given {dataLength}, Read: {readWriteCounter.ReadBytes}"); - } - catch - { + } + catch { this.Data = data; } - } } - public abstract class CustomAttribute - { + public abstract class CustomAttribute { internal abstract byte[] Save(ClassWriterState writerState, AttributeScope scope); } - internal interface ICustomAttributeFactory where T : CustomAttribute - { + internal interface ICustomAttributeFactory where T : CustomAttribute { T Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope); } - internal enum AttributeScope - { + internal enum AttributeScope { Class, Method, Field, diff --git a/JavaAsm/ClassAccessModifiers.cs b/JavaAsm/ClassAccessModifiers.cs index 7852ce8..e02714a 100644 --- a/JavaAsm/ClassAccessModifiers.cs +++ b/JavaAsm/ClassAccessModifiers.cs @@ -47,7 +47,6 @@ public enum FieldAccessModifiers : ushort { } public static class AccessModifiersExtensions { - public static string ToString(ClassAccessModifiers accessModifiers) => string.Join(" ", Enum.GetValues(typeof(ClassAccessModifiers)).OfType().Where(x => accessModifiers.HasFlag(x)).Select(x => x.ToString().ToLower())); public static string ToString(MethodAccessModifiers accessModifiers) => string.Join(" ", Enum.GetValues(typeof(MethodAccessModifiers)).OfType().Where(x => accessModifiers.HasFlag(x)).Select(x => x.ToString().ToLower())); diff --git a/JavaAsm/ClassName.cs b/JavaAsm/ClassName.cs index 37a5ab1..58400da 100644 --- a/JavaAsm/ClassName.cs +++ b/JavaAsm/ClassName.cs @@ -1,35 +1,30 @@ using System; -namespace JavaAsm -{ - public class ClassName - { +namespace JavaAsm { + public class ClassName { public string Name { get; } - public ClassName(string name) - { + public ClassName(string name) { this.Name = name ?? throw new ArgumentNullException(nameof(name)); } - public override string ToString() - { + public override string ToString() { return this.Name.Replace("/", "."); } - private bool Equals(ClassName other) - { + private bool Equals(ClassName other) { return this.Name == other.Name; } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; return obj.GetType() == GetType() && Equals((ClassName) obj); } - public override int GetHashCode() - { + public override int GetHashCode() { return this.Name.GetHashCode(); } } diff --git a/JavaAsm/ClassNode.cs b/JavaAsm/ClassNode.cs index 8e494f9..81a9d3e 100644 --- a/JavaAsm/ClassNode.cs +++ b/JavaAsm/ClassNode.cs @@ -84,8 +84,7 @@ internal void Parse(ClassReaderState readerState) { internal void Save(ClassWriterState writerState) { if (this.SourceFile != null) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.SourceFile)) - throw new Exception( - $"{PredefinedAttributeNames.SourceFile} attribute is already presented on field"); + throw new Exception($"{PredefinedAttributeNames.SourceFile} attribute is already presented on field"); this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.SourceFile, ParsedAttribute = new SourceFileAttribute { @@ -96,8 +95,7 @@ internal void Save(ClassWriterState writerState) { if (this.SourceDebugExtension != null) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.SourceDebugExtension)) - throw new Exception( - $"{PredefinedAttributeNames.SourceDebugExtension} attribute is already presented on field"); + throw new Exception($"{PredefinedAttributeNames.SourceDebugExtension} attribute is already presented on field"); this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.SourceDebugExtension, ParsedAttribute = new SourceDebugExtensionAttribute { @@ -108,8 +106,7 @@ internal void Save(ClassWriterState writerState) { if (this.Signature != null) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Signature)) - throw new Exception( - $"{PredefinedAttributeNames.Signature} attribute is already presented on field"); + throw new Exception($"{PredefinedAttributeNames.Signature} attribute is already presented on field"); this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Signature, ParsedAttribute = new SignatureAttribute { @@ -120,8 +117,7 @@ internal void Save(ClassWriterState writerState) { if (this.InvisibleAnnotations != null && this.InvisibleAnnotations.Count > 0) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeInvisibleAnnotations)) - throw new Exception( - $"{PredefinedAttributeNames.RuntimeInvisibleAnnotations} attribute is already presented on field"); + throw new Exception($"{PredefinedAttributeNames.RuntimeInvisibleAnnotations} attribute is already presented on field"); this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeInvisibleAnnotations, ParsedAttribute = new RuntimeInvisibleAnnotationsAttribute { @@ -132,8 +128,7 @@ internal void Save(ClassWriterState writerState) { if (this.VisibleAnnotations != null && this.VisibleAnnotations.Count > 0) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeVisibleAnnotations)) - throw new Exception( - $"{PredefinedAttributeNames.RuntimeVisibleAnnotations} attribute is already presented on field"); + throw new Exception($"{PredefinedAttributeNames.RuntimeVisibleAnnotations} attribute is already presented on field"); this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeVisibleAnnotations, ParsedAttribute = new RuntimeVisibleAnnotationsAttribute { @@ -144,8 +139,7 @@ internal void Save(ClassWriterState writerState) { if (this.IsDeprecated) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Deprecated)) - throw new Exception( - $"{PredefinedAttributeNames.Deprecated} attribute is already presented on field"); + throw new Exception($"{PredefinedAttributeNames.Deprecated} attribute is already presented on field"); this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Deprecated, ParsedAttribute = new DeprecatedAttribute() @@ -154,8 +148,7 @@ internal void Save(ClassWriterState writerState) { if (this.EnclosingMethod != null) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.EnclosingMethod)) - throw new Exception( - $"{PredefinedAttributeNames.EnclosingMethod} attribute is already presented on field"); + throw new Exception($"{PredefinedAttributeNames.EnclosingMethod} attribute is already presented on field"); this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.EnclosingMethod, ParsedAttribute = this.EnclosingMethod @@ -164,8 +157,7 @@ internal void Save(ClassWriterState writerState) { if (this.InnerClasses != null && this.InnerClasses.Count > 0) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.InnerClasses)) - throw new Exception( - $"{PredefinedAttributeNames.InnerClasses} attribute is already presented on field"); + throw new Exception($"{PredefinedAttributeNames.InnerClasses} attribute is already presented on field"); this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.InnerClasses, ParsedAttribute = new InnerClassesAttribute { diff --git a/JavaAsm/ClassVersion.cs b/JavaAsm/ClassVersion.cs index 9f1d2d7..78d58dc 100644 --- a/JavaAsm/ClassVersion.cs +++ b/JavaAsm/ClassVersion.cs @@ -1,10 +1,8 @@ -namespace JavaAsm -{ +namespace JavaAsm { /// /// Class file version enum /// - public enum ClassVersion : ushort - { + public enum ClassVersion : ushort { Java1P1 = 45, Java1P2, Java1P3, diff --git a/JavaAsm/CustomAttributes/Annotation/AnnotationNode.cs b/JavaAsm/CustomAttributes/Annotation/AnnotationNode.cs index 0d643dc..77adfec 100644 --- a/JavaAsm/CustomAttributes/Annotation/AnnotationNode.cs +++ b/JavaAsm/CustomAttributes/Annotation/AnnotationNode.cs @@ -5,14 +5,11 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes.Annotation -{ - public class AnnotationNode - { +namespace JavaAsm.CustomAttributes.Annotation { + public class AnnotationNode { public TypeDescriptor Type { get; set; } - public class ElementValuePair - { + public class ElementValuePair { public string ElementName { get; set; } public ElementValue Value { get; set; } @@ -20,38 +17,31 @@ public class ElementValuePair public List ElementValuePairs { get; set; } = new List(); - internal static AnnotationNode Parse(Stream stream, ClassReaderState readerState) - { - AnnotationNode annotation = new AnnotationNode - { - Type = TypeDescriptor.Parse(readerState.ConstantPool - .GetEntry(Binary.BigEndian.ReadUInt16(stream)).String) + internal static AnnotationNode Parse(Stream stream, ClassReaderState readerState) { + AnnotationNode annotation = new AnnotationNode { + Type = TypeDescriptor.Parse(readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String) }; ushort elementValuePairsCount = Binary.BigEndian.ReadUInt16(stream); annotation.ElementValuePairs.Capacity = elementValuePairsCount; for (int i = 0; i < elementValuePairsCount; i++) - annotation.ElementValuePairs.Add(new ElementValuePair - { - ElementName = readerState.ConstantPool - .GetEntry(Binary.BigEndian.ReadUInt16(stream)).String, + annotation.ElementValuePairs.Add(new ElementValuePair { + ElementName = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String, Value = ElementValue.Parse(stream, readerState) }); return annotation; } - internal void Write(Stream stream, ClassWriterState writerState) - { + internal void Write(Stream stream, ClassWriterState writerState) { Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new Utf8Entry(this.Type.ToString()))); if (this.ElementValuePairs.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.ElementValuePairs.Count), $"Too many ElementValues: {this.ElementValuePairs.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(stream, (ushort) this.ElementValuePairs.Count); - foreach (ElementValuePair elementValuePair in this.ElementValuePairs) - { + foreach (ElementValuePair elementValuePair in this.ElementValuePairs) { Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new Utf8Entry(elementValuePair.ElementName))); elementValuePair.Value.Write(stream, writerState); } } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/Annotation/ElementValue.cs b/JavaAsm/CustomAttributes/Annotation/ElementValue.cs index 727ed76..03bde18 100644 --- a/JavaAsm/CustomAttributes/Annotation/ElementValue.cs +++ b/JavaAsm/CustomAttributes/Annotation/ElementValue.cs @@ -6,12 +6,9 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes.Annotation -{ - public class ElementValue - { - public enum ElementValueTag - { +namespace JavaAsm.CustomAttributes.Annotation { + public class ElementValue { + public enum ElementValueTag { Byte = 'B', Character = 'C', Double = 'D', @@ -31,8 +28,7 @@ public enum ElementValueTag public object ConstValue { get; set; } - public class EnumConstValueType - { + public class EnumConstValueType { public TypeDescriptor TypeName { get; set; } public string ConstName { get; set; } @@ -46,15 +42,12 @@ public class EnumConstValueType public List ArrayValue { get; set; } - internal static ElementValue Parse(Stream stream, ClassReaderState readerState) - { - ElementValue elementValue = new ElementValue - { + internal static ElementValue Parse(Stream stream, ClassReaderState readerState) { + ElementValue elementValue = new ElementValue { Tag = (ElementValueTag) stream.ReadByteFully() }; - switch (elementValue.Tag) - { + switch (elementValue.Tag) { case ElementValueTag.Byte: case ElementValueTag.Character: case ElementValueTag.Integer: @@ -75,17 +68,13 @@ internal static ElementValue Parse(Stream stream, ClassReaderState readerState) elementValue.ConstValue = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String; break; case ElementValueTag.Enum: - elementValue.EnumConstValue = new EnumConstValueType - { - TypeName = TypeDescriptor.Parse(readerState.ConstantPool - .GetEntry(Binary.BigEndian.ReadUInt16(stream)).String), - ConstName = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)) - .String + elementValue.EnumConstValue = new EnumConstValueType { + TypeName = TypeDescriptor.Parse(readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String), + ConstName = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String }; break; case ElementValueTag.Class: - elementValue.Class = TypeDescriptor.Parse(readerState.ConstantPool - .GetEntry(Binary.BigEndian.ReadUInt16(stream)).String, true); + elementValue.Class = TypeDescriptor.Parse(readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String, true); break; case ElementValueTag.Annotation: elementValue.AnnotationNode = AnnotationNode.Parse(stream, readerState); @@ -96,18 +85,15 @@ internal static ElementValue Parse(Stream stream, ClassReaderState readerState) for (int i = 0; i < arraySize; i++) elementValue.ArrayValue.Add(Parse(stream, readerState)); break; - default: - throw new ArgumentOutOfRangeException(nameof(elementValue.Tag)); + default: throw new ArgumentOutOfRangeException(nameof(elementValue.Tag)); } return elementValue; } - internal void Write(Stream stream, ClassWriterState writerState) - { + internal void Write(Stream stream, ClassWriterState writerState) { stream.WriteByte((byte) this.Tag); - switch (this.Tag) - { + switch (this.Tag) { case ElementValueTag.Byte: case ElementValueTag.Character: case ElementValueTag.Integer: @@ -147,9 +133,8 @@ internal void Write(Stream stream, ClassWriterState writerState) foreach (ElementValue element in this.ArrayValue) element.Write(stream, writerState); break; - default: - throw new ArgumentOutOfRangeException(nameof(this.Tag)); + default: throw new ArgumentOutOfRangeException(nameof(this.Tag)); } } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/AnnotationDefaultAttribute.cs b/JavaAsm/CustomAttributes/AnnotationDefaultAttribute.cs index 4108191..6d4f25c 100644 --- a/JavaAsm/CustomAttributes/AnnotationDefaultAttribute.cs +++ b/JavaAsm/CustomAttributes/AnnotationDefaultAttribute.cs @@ -2,14 +2,11 @@ using JavaAsm.CustomAttributes.Annotation; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class AnnotationDefaultAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class AnnotationDefaultAttribute : CustomAttribute { public ElementValue Value { get; set; } - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); this.Value.Write(attributeDataStream, writerState); @@ -18,14 +15,11 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class AnnotationDefaultAttributeFactory : ICustomAttributeFactory - { - public AnnotationDefaultAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { - return new AnnotationDefaultAttribute - { + internal class AnnotationDefaultAttributeFactory : ICustomAttributeFactory { + public AnnotationDefaultAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { + return new AnnotationDefaultAttribute { Value = ElementValue.Parse(attributeDataStream, readerState) }; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/BootstrapMethodsAttribute.cs b/JavaAsm/CustomAttributes/BootstrapMethodsAttribute.cs index 5cff78c..c8ead35 100644 --- a/JavaAsm/CustomAttributes/BootstrapMethodsAttribute.cs +++ b/JavaAsm/CustomAttributes/BootstrapMethodsAttribute.cs @@ -6,41 +6,35 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class BootstrapMethod - { +namespace JavaAsm.CustomAttributes { + public class BootstrapMethod { public Handle BootstrapMethodReference { get; } public List Arguments { get; } = new List(); - public BootstrapMethod(Handle bootstrapMethodReference) - { + public BootstrapMethod(Handle bootstrapMethodReference) { this.BootstrapMethodReference = bootstrapMethodReference; } - public BootstrapMethod(Handle bootstrapMethodReference, List arguments) - { + public BootstrapMethod(Handle bootstrapMethodReference, List arguments) { this.BootstrapMethodReference = bootstrapMethodReference; this.Arguments = arguments; } - public bool Equals(BootstrapMethod other) - { + public bool Equals(BootstrapMethod other) { return this.BootstrapMethodReference.Equals(other.BootstrapMethodReference) && this.Arguments.Equals(other.Arguments); } - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((BootstrapMethod)obj); + public override bool Equals(object obj) { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((BootstrapMethod) obj); } - public override int GetHashCode() - { - unchecked - { + public override int GetHashCode() { + unchecked { return (this.BootstrapMethodReference.GetHashCode() * 397) ^ this.Arguments.GetHashCode(); } } @@ -83,7 +77,8 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope val = ((Handle) argument).ToConstantPool(); } else if (argument is MethodDescriptor) { - val = new MethodTypeEntry(new Utf8Entry(((MethodDescriptor) argument).ToString())); } + val = new MethodTypeEntry(new Utf8Entry(((MethodDescriptor) argument).ToString())); + } else { throw new ArgumentOutOfRangeException(nameof(argument), $"Can't encode value of type {argument.GetType()}"); } @@ -97,16 +92,13 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class BootstrapMethodsAttributeFactory : ICustomAttributeFactory - { - public BootstrapMethodsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class BootstrapMethodsAttributeFactory : ICustomAttributeFactory { + public BootstrapMethodsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { BootstrapMethodsAttribute attribute = new BootstrapMethodsAttribute(); ushort bootstrapMethodsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.BootstrapMethods.Capacity = bootstrapMethodsCount; - for (int i = 0; i < bootstrapMethodsCount; i++) - { + for (int i = 0; i < bootstrapMethodsCount; i++) { BootstrapMethod bootstrapMethod = new BootstrapMethod( Handle.FromConstantPool( readerState.ConstantPool.GetEntry( @@ -147,10 +139,11 @@ public BootstrapMethodsAttribute Parse(Stream attributeDataStream, uint attribut bootstrapMethod.Arguments.Add(item); } + attribute.BootstrapMethods.Add(bootstrapMethod); } return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/CodeAttribute.cs b/JavaAsm/CustomAttributes/CodeAttribute.cs index 4c50302..f079a13 100644 --- a/JavaAsm/CustomAttributes/CodeAttribute.cs +++ b/JavaAsm/CustomAttributes/CodeAttribute.cs @@ -6,18 +6,15 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class CodeAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class CodeAttribute : CustomAttribute { public ushort MaxStack { get; set; } public ushort MaxLocals { get; set; } public byte[] Code { get; set; } - public class ExceptionTableEntry - { + public class ExceptionTableEntry { public ushort StartPc { get; set; } public ushort EndPc { get; set; } @@ -31,8 +28,7 @@ public class ExceptionTableEntry public List Attributes { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); Binary.BigEndian.Write(attributeDataStream, this.MaxStack); @@ -46,13 +42,11 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope if (this.ExceptionTable.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.ExceptionTable.Count), $"Exception table too big: {this.ExceptionTable.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(attributeDataStream, (ushort) this.ExceptionTable.Count); - foreach (ExceptionTableEntry exceptionTableEntry in this.ExceptionTable) - { + foreach (ExceptionTableEntry exceptionTableEntry in this.ExceptionTable) { Binary.BigEndian.Write(attributeDataStream, exceptionTableEntry.StartPc); Binary.BigEndian.Write(attributeDataStream, exceptionTableEntry.EndPc); Binary.BigEndian.Write(attributeDataStream, exceptionTableEntry.HandlerPc); - Binary.BigEndian.Write(attributeDataStream, (ushort) (exceptionTableEntry.CatchType == null ? 0 : - writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(exceptionTableEntry.CatchType.Name))))); + Binary.BigEndian.Write(attributeDataStream, (ushort) (exceptionTableEntry.CatchType == null ? 0 : writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(exceptionTableEntry.CatchType.Name))))); } if (this.Attributes.Count > ushort.MaxValue) @@ -65,16 +59,13 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class CodeAttributeFactory : ICustomAttributeFactory - { - public CodeAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class CodeAttributeFactory : ICustomAttributeFactory { + public CodeAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { ushort maxStack = Binary.BigEndian.ReadUInt16(attributeDataStream); ushort maxLocals = Binary.BigEndian.ReadUInt16(attributeDataStream); byte[] code = new byte[Binary.BigEndian.ReadUInt32(attributeDataStream)]; attributeDataStream.Read(code); - CodeAttribute attribute = new CodeAttribute - { + CodeAttribute attribute = new CodeAttribute { MaxStack = maxStack, MaxLocals = maxLocals, Code = code @@ -82,21 +73,16 @@ public CodeAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ushort exceptionTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.ExceptionTable.Capacity = exceptionTableSize; - for (int i = 0; i < exceptionTableSize; i++) - { - CodeAttribute.ExceptionTableEntry exceptionTableEntry = new CodeAttribute.ExceptionTableEntry - { + for (int i = 0; i < exceptionTableSize; i++) { + CodeAttribute.ExceptionTableEntry exceptionTableEntry = new CodeAttribute.ExceptionTableEntry { StartPc = Binary.BigEndian.ReadUInt16(attributeDataStream), EndPc = Binary.BigEndian.ReadUInt16(attributeDataStream), HandlerPc = Binary.BigEndian.ReadUInt16(attributeDataStream) }; ushort catchTypeIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); - if (catchTypeIndex != 0) - { - exceptionTableEntry.CatchType = new ClassName(readerState.ConstantPool - .GetEntry(catchTypeIndex) - .Name.String); + if (catchTypeIndex != 0) { + exceptionTableEntry.CatchType = new ClassName(readerState.ConstantPool.GetEntry(catchTypeIndex).Name.String); } attribute.ExceptionTable.Add(exceptionTableEntry); @@ -110,4 +96,4 @@ public CodeAttribute Parse(Stream attributeDataStream, uint attributeDataLength, return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/ConstantValueAttribute.cs b/JavaAsm/CustomAttributes/ConstantValueAttribute.cs index efe041e..ebb1027 100644 --- a/JavaAsm/CustomAttributes/ConstantValueAttribute.cs +++ b/JavaAsm/CustomAttributes/ConstantValueAttribute.cs @@ -4,20 +4,28 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class ConstantValueAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class ConstantValueAttribute : CustomAttribute { public object Value { get; set; } internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { ushort value; switch (this.Value) { - case long longValue: value = writerState.ConstantPool.Find(new LongEntry(longValue)); break; - case float floatValue: value = writerState.ConstantPool.Find(new FloatEntry(floatValue)); break; - case double doubleValue: value = writerState.ConstantPool.Find(new DoubleEntry(doubleValue)); break; - case int integerValue: value = writerState.ConstantPool.Find(new IntegerEntry(integerValue)); break; - case string stringValue: value = writerState.ConstantPool.Find(new StringEntry(new Utf8Entry(stringValue))); break; + case long longValue: + value = writerState.ConstantPool.Find(new LongEntry(longValue)); + break; + case float floatValue: + value = writerState.ConstantPool.Find(new FloatEntry(floatValue)); + break; + case double doubleValue: + value = writerState.ConstantPool.Find(new DoubleEntry(doubleValue)); + break; + case int integerValue: + value = writerState.ConstantPool.Find(new IntegerEntry(integerValue)); + break; + case string stringValue: + value = writerState.ConstantPool.Find(new StringEntry(new Utf8Entry(stringValue))); + break; default: throw new ArgumentOutOfRangeException(nameof(this.Value), $"Can't encode value of type {this.Value.GetType()}"); } @@ -27,22 +35,30 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class ConstantValueAttributeFactory : ICustomAttributeFactory - { - public ConstantValueAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class ConstantValueAttributeFactory : ICustomAttributeFactory { + public ConstantValueAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { Entry entry = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)); object value; switch (entry) { - case LongEntry longEntry: value = longEntry.Value; break; - case FloatEntry floatEntry: value = floatEntry.Value; break; - case DoubleEntry doubleEntry: value = doubleEntry.Value; break; - case IntegerEntry integerEntry: value = integerEntry.Value; break; - case StringEntry stringEntry: value = stringEntry.Value.String; break; + case LongEntry longEntry: + value = longEntry.Value; + break; + case FloatEntry floatEntry: + value = floatEntry.Value; + break; + case DoubleEntry doubleEntry: + value = doubleEntry.Value; + break; + case IntegerEntry integerEntry: + value = integerEntry.Value; + break; + case StringEntry stringEntry: + value = stringEntry.Value.String; + break; default: throw new ArgumentOutOfRangeException(nameof(entry), $"Can't use constant pool entry of type {entry.GetType()} as constant value"); } return new ConstantValueAttribute {Value = value}; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/DeprecatedAttribute.cs b/JavaAsm/CustomAttributes/DeprecatedAttribute.cs index 6f1a867..bf2e04b 100644 --- a/JavaAsm/CustomAttributes/DeprecatedAttribute.cs +++ b/JavaAsm/CustomAttributes/DeprecatedAttribute.cs @@ -1,15 +1,12 @@ using System.IO; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class DeprecatedAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class DeprecatedAttribute : CustomAttribute { internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) => new byte[0]; } - internal class DeprecatedAttributeFactory : ICustomAttributeFactory - { + internal class DeprecatedAttributeFactory : ICustomAttributeFactory { public DeprecatedAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) => new DeprecatedAttribute(); } } \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/EnclosingMethodAttribute.cs b/JavaAsm/CustomAttributes/EnclosingMethodAttribute.cs index 12cc38d..ec960b4 100644 --- a/JavaAsm/CustomAttributes/EnclosingMethodAttribute.cs +++ b/JavaAsm/CustomAttributes/EnclosingMethodAttribute.cs @@ -3,28 +3,23 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class EnclosingMethodAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class EnclosingMethodAttribute : CustomAttribute { public ClassName Class { get; set; } public string MethodName { get; set; } public MethodDescriptor MethodDescriptor { get; set; } - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(this.Class.Name)))); - if (this.MethodName == null && this.MethodDescriptor == null) - { + if (this.MethodName == null && this.MethodDescriptor == null) { Binary.BigEndian.Write(attributeDataStream, (ushort) 0); } - else - { + else { Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new NameAndTypeEntry(new Utf8Entry(this.MethodName), new Utf8Entry(this.MethodDescriptor.ToString())))); @@ -34,14 +29,10 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class EnclosingMethodAttributeFactory : ICustomAttributeFactory - { - public EnclosingMethodAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { - EnclosingMethodAttribute attribute = new EnclosingMethodAttribute - { - Class = new ClassName(readerState.ConstantPool - .GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).Name.String) + internal class EnclosingMethodAttributeFactory : ICustomAttributeFactory { + public EnclosingMethodAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { + EnclosingMethodAttribute attribute = new EnclosingMethodAttribute { + Class = new ClassName(readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).Name.String) }; ushort nameAndTypeEntryIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); @@ -56,4 +47,4 @@ public EnclosingMethodAttribute Parse(Stream attributeDataStream, uint attribute return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/ExceptionsAttribute.cs b/JavaAsm/CustomAttributes/ExceptionsAttribute.cs index f07371b..32c1f21 100644 --- a/JavaAsm/CustomAttributes/ExceptionsAttribute.cs +++ b/JavaAsm/CustomAttributes/ExceptionsAttribute.cs @@ -5,14 +5,11 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class ExceptionsAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class ExceptionsAttribute : CustomAttribute { public List ExceptionTable { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.ExceptionTable.Count > ushort.MaxValue) @@ -27,19 +24,16 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class ExceptionsAttributeFactory : ICustomAttributeFactory - { - public ExceptionsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class ExceptionsAttributeFactory : ICustomAttributeFactory { + public ExceptionsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { ExceptionsAttribute attribute = new ExceptionsAttribute(); ushort count = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.ExceptionTable.Capacity = count; for (int i = 0; i < count; i++) - attribute.ExceptionTable.Add(new ClassName(readerState.ConstantPool - .GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).Name.String)); + attribute.ExceptionTable.Add(new ClassName(readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).Name.String)); return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/InnerClassesAttribute.cs b/JavaAsm/CustomAttributes/InnerClassesAttribute.cs index ca526d7..c593189 100644 --- a/JavaAsm/CustomAttributes/InnerClassesAttribute.cs +++ b/JavaAsm/CustomAttributes/InnerClassesAttribute.cs @@ -5,27 +5,21 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class InnerClassesAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class InnerClassesAttribute : CustomAttribute { public List Classes { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.Classes.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.Classes.Count), $"Too many inner classes: {this.Classes.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(attributeDataStream, (ushort) this.Classes.Count); - foreach (InnerClass innerClass in this.Classes) - { + foreach (InnerClass innerClass in this.Classes) { Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(innerClass.InnerClassName.Name)))); - Binary.BigEndian.Write(attributeDataStream, innerClass.OuterClassName == null ? (ushort) 0 : - writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(innerClass.OuterClassName.Name)))); - Binary.BigEndian.Write(attributeDataStream, innerClass.InnerName == null ? (ushort) 0 : - writerState.ConstantPool.Find(new Utf8Entry(innerClass.InnerName))); + Binary.BigEndian.Write(attributeDataStream, innerClass.OuterClassName == null ? (ushort) 0 : writerState.ConstantPool.Find(new ClassEntry(new Utf8Entry(innerClass.OuterClassName.Name)))); + Binary.BigEndian.Write(attributeDataStream, innerClass.InnerName == null ? (ushort) 0 : writerState.ConstantPool.Find(new Utf8Entry(innerClass.InnerName))); Binary.BigEndian.Write(attributeDataStream, (ushort) innerClass.Access); } @@ -33,8 +27,7 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - public class InnerClass - { + public class InnerClass { public ClassName InnerClassName { get; set; } public ClassName OuterClassName { get; set; } @@ -43,35 +36,27 @@ public class InnerClass public ClassAccessModifiers Access { get; set; } - public override string ToString() - { + public override string ToString() { return $"{AccessModifiersExtensions.ToString(this.Access)} {this.InnerClassName?.ToString() ?? "null"} {this.OuterClassName?.ToString() ?? "null"} {this.InnerName?.ToString() ?? "null"}"; } } - internal class InnerClassesAttributeFactory : ICustomAttributeFactory - { - public InnerClassesAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class InnerClassesAttributeFactory : ICustomAttributeFactory { + public InnerClassesAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { InnerClassesAttribute attribute = new InnerClassesAttribute(); ushort classesCount = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.Classes.Capacity = classesCount; - for (int i = 0; i < classesCount; i++) - { - InnerClass innerClass = new InnerClass - { - InnerClassName = new ClassName(readerState.ConstantPool - .GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).Name.String) + for (int i = 0; i < classesCount; i++) { + InnerClass innerClass = new InnerClass { + InnerClassName = new ClassName(readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).Name.String) }; ushort outerClassIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); if (outerClassIndex != 0) - innerClass.OuterClassName = new ClassName(readerState.ConstantPool - .GetEntry(outerClassIndex).Name.String); + innerClass.OuterClassName = new ClassName(readerState.ConstantPool.GetEntry(outerClassIndex).Name.String); ushort innerNameIndex = Binary.BigEndian.ReadUInt16(attributeDataStream); if (innerNameIndex != 0) - innerClass.InnerName = readerState.ConstantPool - .GetEntry(innerNameIndex).String; + innerClass.InnerName = readerState.ConstantPool.GetEntry(innerNameIndex).String; innerClass.Access = (ClassAccessModifiers) Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.Classes.Add(innerClass); } @@ -79,4 +64,4 @@ public InnerClassesAttribute Parse(Stream attributeDataStream, uint attributeDat return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/LineNumberTableAttribute.cs b/JavaAsm/CustomAttributes/LineNumberTableAttribute.cs index 5f9d772..a973399 100644 --- a/JavaAsm/CustomAttributes/LineNumberTableAttribute.cs +++ b/JavaAsm/CustomAttributes/LineNumberTableAttribute.cs @@ -4,12 +4,9 @@ using BinaryEncoding; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class LineNumberTableAttribute : CustomAttribute - { - public class LineNumberTableEntry - { +namespace JavaAsm.CustomAttributes { + public class LineNumberTableAttribute : CustomAttribute { + public class LineNumberTableEntry { public ushort StartPc { get; set; } public ushort LineNumber { get; set; } @@ -17,15 +14,13 @@ public class LineNumberTableEntry public List LineNumberTable { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.LineNumberTable.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.LineNumberTable.Count), $"Line number table too big: {this.LineNumberTable.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(attributeDataStream, (ushort) this.LineNumberTable.Count); - foreach (LineNumberTableEntry exceptionTableEntry in this.LineNumberTable) - { + foreach (LineNumberTableEntry exceptionTableEntry in this.LineNumberTable) { Binary.BigEndian.Write(attributeDataStream, exceptionTableEntry.StartPc); Binary.BigEndian.Write(attributeDataStream, exceptionTableEntry.LineNumber); } @@ -34,17 +29,14 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class LineNumberTableAttributeFactory : ICustomAttributeFactory - { - public LineNumberTableAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class LineNumberTableAttributeFactory : ICustomAttributeFactory { + public LineNumberTableAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { LineNumberTableAttribute attribute = new LineNumberTableAttribute(); ushort exceptionTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.LineNumberTable.Capacity = exceptionTableSize; for (int i = 0; i < exceptionTableSize; i++) - attribute.LineNumberTable.Add(new LineNumberTableAttribute.LineNumberTableEntry - { + attribute.LineNumberTable.Add(new LineNumberTableAttribute.LineNumberTableEntry { StartPc = Binary.BigEndian.ReadUInt16(attributeDataStream), LineNumber = Binary.BigEndian.ReadUInt16(attributeDataStream) }); @@ -52,4 +44,4 @@ public LineNumberTableAttribute Parse(Stream attributeDataStream, uint attribute return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/LocalVariableTableAttribute.cs b/JavaAsm/CustomAttributes/LocalVariableTableAttribute.cs index 20acf0e..626f61e 100644 --- a/JavaAsm/CustomAttributes/LocalVariableTableAttribute.cs +++ b/JavaAsm/CustomAttributes/LocalVariableTableAttribute.cs @@ -5,12 +5,9 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class LocalVariableTableAttribute : CustomAttribute - { - public class LocalVariableTableEntry - { +namespace JavaAsm.CustomAttributes { + public class LocalVariableTableAttribute : CustomAttribute { + public class LocalVariableTableEntry { public ushort StartPc { get; set; } public ushort Length { get; set; } @@ -24,15 +21,13 @@ public class LocalVariableTableEntry public List LocalVariableTable { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.LocalVariableTable.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.LocalVariableTable.Count), $"Local variable table is too big: {this.LocalVariableTable.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(attributeDataStream, (ushort) this.LocalVariableTable.Count); - foreach (LocalVariableTableEntry localVariableTableEntry in this.LocalVariableTable) - { + foreach (LocalVariableTableEntry localVariableTableEntry in this.LocalVariableTable) { Binary.BigEndian.Write(attributeDataStream, localVariableTableEntry.StartPc); Binary.BigEndian.Write(attributeDataStream, localVariableTableEntry.Length); Binary.BigEndian.Write(attributeDataStream, @@ -46,17 +41,14 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class LocalVariableTableAttributeFactory : ICustomAttributeFactory - { - public LocalVariableTableAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class LocalVariableTableAttributeFactory : ICustomAttributeFactory { + public LocalVariableTableAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { LocalVariableTableAttribute attribute = new LocalVariableTableAttribute(); ushort localVariableTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.LocalVariableTable.Capacity = localVariableTableSize; for (int i = 0; i < localVariableTableSize; i++) - attribute.LocalVariableTable.Add(new LocalVariableTableAttribute.LocalVariableTableEntry - { + attribute.LocalVariableTable.Add(new LocalVariableTableAttribute.LocalVariableTableEntry { StartPc = Binary.BigEndian.ReadUInt16(attributeDataStream), Length = Binary.BigEndian.ReadUInt16(attributeDataStream), Name = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).String, @@ -67,4 +59,4 @@ public LocalVariableTableAttribute Parse(Stream attributeDataStream, uint attrib return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/LocalVariableTypeTableAttribute.cs b/JavaAsm/CustomAttributes/LocalVariableTypeTableAttribute.cs index 08129ba..a0a5e06 100644 --- a/JavaAsm/CustomAttributes/LocalVariableTypeTableAttribute.cs +++ b/JavaAsm/CustomAttributes/LocalVariableTypeTableAttribute.cs @@ -5,12 +5,9 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class LocalVariableTypeTableAttribute : CustomAttribute - { - public class LocalVariableTypeTableEntry - { +namespace JavaAsm.CustomAttributes { + public class LocalVariableTypeTableAttribute : CustomAttribute { + public class LocalVariableTypeTableEntry { public ushort StartPc { get; set; } public ushort Length { get; set; } @@ -24,15 +21,13 @@ public class LocalVariableTypeTableEntry public List LocalVariableTypeTable { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.LocalVariableTypeTable.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.LocalVariableTypeTable.Count), $"Local variable type table is too big: {this.LocalVariableTypeTable.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(attributeDataStream, (ushort) this.LocalVariableTypeTable.Count); - foreach (LocalVariableTypeTableEntry localVariableTypeTableEntry in this.LocalVariableTypeTable) - { + foreach (LocalVariableTypeTableEntry localVariableTypeTableEntry in this.LocalVariableTypeTable) { Binary.BigEndian.Write(attributeDataStream, localVariableTypeTableEntry.StartPc); Binary.BigEndian.Write(attributeDataStream, localVariableTypeTableEntry.Length); Binary.BigEndian.Write(attributeDataStream, @@ -46,17 +41,14 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class LocalVariableTypeTableAttributeFactory : ICustomAttributeFactory - { - public LocalVariableTypeTableAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class LocalVariableTypeTableAttributeFactory : ICustomAttributeFactory { + public LocalVariableTypeTableAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { LocalVariableTypeTableAttribute attribute = new LocalVariableTypeTableAttribute(); ushort localVariableTypeTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.LocalVariableTypeTable.Capacity = localVariableTypeTableSize; for (int i = 0; i < localVariableTypeTableSize; i++) - attribute.LocalVariableTypeTable.Add(new LocalVariableTypeTableAttribute.LocalVariableTypeTableEntry - { + attribute.LocalVariableTypeTable.Add(new LocalVariableTypeTableAttribute.LocalVariableTypeTableEntry { StartPc = Binary.BigEndian.ReadUInt16(attributeDataStream), Length = Binary.BigEndian.ReadUInt16(attributeDataStream), Name = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).String, @@ -67,4 +59,4 @@ public LocalVariableTypeTableAttribute Parse(Stream attributeDataStream, uint at return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/MethodParametersAttribute.cs b/JavaAsm/CustomAttributes/MethodParametersAttribute.cs index 29c653d..4e5fe04 100644 --- a/JavaAsm/CustomAttributes/MethodParametersAttribute.cs +++ b/JavaAsm/CustomAttributes/MethodParametersAttribute.cs @@ -6,12 +6,9 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class MethodParametersAttribute : CustomAttribute - { - public class Parameter - { +namespace JavaAsm.CustomAttributes { + public class MethodParametersAttribute : CustomAttribute { + public class Parameter { public string Name { get; set; } public ClassAccessModifiers Access { get; set; } @@ -19,15 +16,13 @@ public class Parameter public List Parameters { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.Parameters.Count > byte.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.Parameters.Count), $"Too many parameters: {this.Parameters.Count} > {byte.MaxValue}"); attributeDataStream.WriteByte((byte) this.Parameters.Count); - foreach (Parameter parameter in this.Parameters) - { + foreach (Parameter parameter in this.Parameters) { Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new Utf8Entry(parameter.Name))); Binary.BigEndian.Write(attributeDataStream, (ushort) parameter.Access); @@ -37,17 +32,14 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class MethodParametersAttributeFactory : ICustomAttributeFactory - { - public MethodParametersAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class MethodParametersAttributeFactory : ICustomAttributeFactory { + public MethodParametersAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { MethodParametersAttribute attribute = new MethodParametersAttribute(); byte exceptionTableSize = attributeDataStream.ReadByteFully(); attribute.Parameters.Capacity = exceptionTableSize; for (int i = 0; i < exceptionTableSize; i++) - attribute.Parameters.Add(new MethodParametersAttribute.Parameter - { + attribute.Parameters.Add(new MethodParametersAttribute.Parameter { Name = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).String, Access = (ClassAccessModifiers) Binary.BigEndian.ReadUInt16(attributeDataStream) }); @@ -55,4 +47,4 @@ public MethodParametersAttribute Parse(Stream attributeDataStream, uint attribut return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/RuntimeInvisibleAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeInvisibleAnnotationsAttribute.cs index b788e78..4fdb6e3 100644 --- a/JavaAsm/CustomAttributes/RuntimeInvisibleAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeInvisibleAnnotationsAttribute.cs @@ -5,14 +5,11 @@ using JavaAsm.CustomAttributes.Annotation; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class RuntimeInvisibleAnnotationsAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class RuntimeInvisibleAnnotationsAttribute : CustomAttribute { public List Annotations { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.Annotations.Count > ushort.MaxValue) @@ -25,10 +22,8 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class RuntimeInvisibleAnnotationsAttributeFactory : ICustomAttributeFactory - { - public RuntimeInvisibleAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class RuntimeInvisibleAnnotationsAttributeFactory : ICustomAttributeFactory { + public RuntimeInvisibleAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { RuntimeInvisibleAnnotationsAttribute attribute = new RuntimeInvisibleAnnotationsAttribute(); ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); @@ -37,7 +32,6 @@ public RuntimeInvisibleAnnotationsAttribute Parse(Stream attributeDataStream, ui attribute.Annotations.Add(AnnotationNode.Parse(attributeDataStream, readerState)); return attribute; - } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/RuntimeInvisibleParameterAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeInvisibleParameterAnnotationsAttribute.cs index bf8750f..3a517f1 100644 --- a/JavaAsm/CustomAttributes/RuntimeInvisibleParameterAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeInvisibleParameterAnnotationsAttribute.cs @@ -6,31 +6,25 @@ using JavaAsm.Helpers; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class ParameterAnnotations - { +namespace JavaAsm.CustomAttributes { + public class ParameterAnnotations { public List Annotations { get; set; } = new List(); } - public class RuntimeInvisibleParameterAnnotationsAttribute : CustomAttribute - { - + public class RuntimeInvisibleParameterAnnotationsAttribute : CustomAttribute { public List Parameters { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.Parameters.Count > byte.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.Parameters.Count), $"Number of parameters is too big: {this.Parameters.Count} > {byte.MaxValue}"); attributeDataStream.WriteByte((byte) this.Parameters.Count); - foreach (ParameterAnnotations parameter in this.Parameters) - { + foreach (ParameterAnnotations parameter in this.Parameters) { if (parameter.Annotations.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(parameter.Annotations.Count), $"Number of annotations is too big: {parameter.Annotations.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(attributeDataStream, (ushort)parameter.Annotations.Count); + Binary.BigEndian.Write(attributeDataStream, (ushort) parameter.Annotations.Count); foreach (AnnotationNode annotation in parameter.Annotations) annotation.Write(attributeDataStream, writerState); } @@ -39,16 +33,13 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class RuntimeInvisibleParameterAnnotationsAttributeFactory : ICustomAttributeFactory - { - public RuntimeInvisibleParameterAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class RuntimeInvisibleParameterAnnotationsAttributeFactory : ICustomAttributeFactory { + public RuntimeInvisibleParameterAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { RuntimeInvisibleParameterAnnotationsAttribute attribute = new RuntimeInvisibleParameterAnnotationsAttribute(); byte parametersCount = attributeDataStream.ReadByteFully(); attribute.Parameters.Capacity = parametersCount; - for (int i = 0; i < parametersCount; i++) - { + for (int i = 0; i < parametersCount; i++) { ParameterAnnotations parameter = new ParameterAnnotations(); ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); parameter.Annotations.Capacity = annotationsCount; @@ -60,4 +51,4 @@ public RuntimeInvisibleParameterAnnotationsAttribute Parse(Stream attributeDataS return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/RuntimeInvisibleTypeAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeInvisibleTypeAnnotationsAttribute.cs index b66a820..10cc8ac 100644 --- a/JavaAsm/CustomAttributes/RuntimeInvisibleTypeAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeInvisibleTypeAnnotationsAttribute.cs @@ -5,14 +5,11 @@ using JavaAsm.CustomAttributes.TypeAnnotation; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class RuntimeInvisibleTypeAnnotationsAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class RuntimeInvisibleTypeAnnotationsAttribute : CustomAttribute { public List Annotations { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.Annotations.Count > ushort.MaxValue) @@ -25,10 +22,8 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class RuntimeInvisibleTypeAnnotationsAttributeFactory : ICustomAttributeFactory - { - public RuntimeInvisibleTypeAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class RuntimeInvisibleTypeAnnotationsAttributeFactory : ICustomAttributeFactory { + public RuntimeInvisibleTypeAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { RuntimeInvisibleTypeAnnotationsAttribute attribute = new RuntimeInvisibleTypeAnnotationsAttribute(); ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); @@ -39,4 +34,4 @@ public RuntimeInvisibleTypeAnnotationsAttribute Parse(Stream attributeDataStream return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/RuntimeVisibleAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeVisibleAnnotationsAttribute.cs index 24dabf7..f3c74fd 100644 --- a/JavaAsm/CustomAttributes/RuntimeVisibleAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeVisibleAnnotationsAttribute.cs @@ -5,14 +5,11 @@ using JavaAsm.CustomAttributes.Annotation; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class RuntimeVisibleAnnotationsAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class RuntimeVisibleAnnotationsAttribute : CustomAttribute { public List Annotations { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.Annotations.Count > ushort.MaxValue) @@ -25,10 +22,8 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class RuntimeVisibleAnnotationsAttributeFactory : ICustomAttributeFactory - { - public RuntimeVisibleAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class RuntimeVisibleAnnotationsAttributeFactory : ICustomAttributeFactory { + public RuntimeVisibleAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { RuntimeVisibleAnnotationsAttribute attribute = new RuntimeVisibleAnnotationsAttribute(); ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); @@ -39,4 +34,4 @@ public RuntimeVisibleAnnotationsAttribute Parse(Stream attributeDataStream, uint return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/RuntimeVisibleParameterAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeVisibleParameterAnnotationsAttribute.cs index 707c8d2..1045fb8 100644 --- a/JavaAsm/CustomAttributes/RuntimeVisibleParameterAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeVisibleParameterAnnotationsAttribute.cs @@ -6,21 +6,17 @@ using JavaAsm.Helpers; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class RuntimeVisibleParameterAnnotationsAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class RuntimeVisibleParameterAnnotationsAttribute : CustomAttribute { public List Parameters { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.Parameters.Count > byte.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.Parameters.Count), $"Number of parameters is too big: {this.Parameters.Count} > {byte.MaxValue}"); attributeDataStream.WriteByte((byte) this.Parameters.Count); - foreach (ParameterAnnotations parameter in this.Parameters) - { + foreach (ParameterAnnotations parameter in this.Parameters) { if (parameter.Annotations.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(parameter.Annotations.Count), $"Number of annotations is too big: {parameter.Annotations.Count} > {ushort.MaxValue}"); @@ -33,16 +29,13 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class RuntimeVisibleParameterAnnotationsAttributeFactory : ICustomAttributeFactory - { - public RuntimeVisibleParameterAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class RuntimeVisibleParameterAnnotationsAttributeFactory : ICustomAttributeFactory { + public RuntimeVisibleParameterAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { RuntimeVisibleParameterAnnotationsAttribute attribute = new RuntimeVisibleParameterAnnotationsAttribute(); byte parametersCount = attributeDataStream.ReadByteFully(); attribute.Parameters.Capacity = parametersCount; - for (int i = 0; i < parametersCount; i++) - { + for (int i = 0; i < parametersCount; i++) { ParameterAnnotations parameter = new ParameterAnnotations(); ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); parameter.Annotations.Capacity = annotationsCount; @@ -54,4 +47,4 @@ public RuntimeVisibleParameterAnnotationsAttribute Parse(Stream attributeDataStr return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/RuntimeVisibleTypeAnnotationsAttribute.cs b/JavaAsm/CustomAttributes/RuntimeVisibleTypeAnnotationsAttribute.cs index a342fb1..558916f 100644 --- a/JavaAsm/CustomAttributes/RuntimeVisibleTypeAnnotationsAttribute.cs +++ b/JavaAsm/CustomAttributes/RuntimeVisibleTypeAnnotationsAttribute.cs @@ -5,14 +5,11 @@ using JavaAsm.CustomAttributes.TypeAnnotation; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class RuntimeVisibleTypeAnnotationsAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class RuntimeVisibleTypeAnnotationsAttribute : CustomAttribute { public List Annotations { get; set; } = new List(); - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { using (MemoryStream attributeDataStream = new MemoryStream()) { if (this.Annotations.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.Annotations.Count), $"Number of annotations is too big: {this.Annotations.Count} > {ushort.MaxValue}"); @@ -25,10 +22,8 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class RuntimeVisibleTypeAnnotationsAttributeFactory : ICustomAttributeFactory - { - public RuntimeVisibleTypeAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + internal class RuntimeVisibleTypeAnnotationsAttributeFactory : ICustomAttributeFactory { + public RuntimeVisibleTypeAnnotationsAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { RuntimeVisibleTypeAnnotationsAttribute attribute = new RuntimeVisibleTypeAnnotationsAttribute(); ushort annotationsCount = Binary.BigEndian.ReadUInt16(attributeDataStream); @@ -39,4 +34,4 @@ public RuntimeVisibleTypeAnnotationsAttribute Parse(Stream attributeDataStream, return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/SignatureAttribute.cs b/JavaAsm/CustomAttributes/SignatureAttribute.cs index c8dd174..14222a3 100644 --- a/JavaAsm/CustomAttributes/SignatureAttribute.cs +++ b/JavaAsm/CustomAttributes/SignatureAttribute.cs @@ -3,14 +3,11 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class SignatureAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class SignatureAttribute : CustomAttribute { public string Value { get; set; } - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new Utf8Entry(this.Value))); @@ -19,14 +16,11 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class SignatureAttributeFactory : ICustomAttributeFactory - { - public SignatureAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { - return new SignatureAttribute - { + internal class SignatureAttributeFactory : ICustomAttributeFactory { + public SignatureAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { + return new SignatureAttribute { Value = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).String }; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/SourceDebugExtensionAttribute.cs b/JavaAsm/CustomAttributes/SourceDebugExtensionAttribute.cs index bead31d..6e7764f 100644 --- a/JavaAsm/CustomAttributes/SourceDebugExtensionAttribute.cs +++ b/JavaAsm/CustomAttributes/SourceDebugExtensionAttribute.cs @@ -2,26 +2,20 @@ using JavaAsm.Helpers; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class SourceDebugExtensionAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class SourceDebugExtensionAttribute : CustomAttribute { public string Value { get; set; } - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { return ModifiedUtf8Helper.Encode(this.Value); } } - internal class SourceDebugExtensionFactory : ICustomAttributeFactory - { - public SourceDebugExtensionAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { - return new SourceDebugExtensionAttribute - { + internal class SourceDebugExtensionFactory : ICustomAttributeFactory { + public SourceDebugExtensionAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { + return new SourceDebugExtensionAttribute { Value = ModifiedUtf8Helper.Decode(attributeDataStream.ReadBytes(attributeDataLength)) }; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/SourceFileAttribute.cs b/JavaAsm/CustomAttributes/SourceFileAttribute.cs index d9487ff..5af5e8c 100644 --- a/JavaAsm/CustomAttributes/SourceFileAttribute.cs +++ b/JavaAsm/CustomAttributes/SourceFileAttribute.cs @@ -3,14 +3,11 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class SourceFileAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class SourceFileAttribute : CustomAttribute { public string Value { get; set; } - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); Binary.BigEndian.Write(attributeDataStream, writerState.ConstantPool.Find(new Utf8Entry(this.Value))); @@ -19,14 +16,11 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class SourceFileAttributeFactory : ICustomAttributeFactory - { - public SourceFileAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { - return new SourceFileAttribute - { + internal class SourceFileAttributeFactory : ICustomAttributeFactory { + public SourceFileAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { + return new SourceFileAttribute { Value = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(attributeDataStream)).String }; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/StackMapTableAttribute.cs b/JavaAsm/CustomAttributes/StackMapTableAttribute.cs index 913c9c9..1d77032 100644 --- a/JavaAsm/CustomAttributes/StackMapTableAttribute.cs +++ b/JavaAsm/CustomAttributes/StackMapTableAttribute.cs @@ -6,12 +6,9 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes -{ - public class StackMapTableAttribute : CustomAttribute - { - public enum VerificationElementType - { +namespace JavaAsm.CustomAttributes { + public class StackMapTableAttribute : CustomAttribute { + public enum VerificationElementType { Top, Integer, Float, @@ -23,39 +20,33 @@ public enum VerificationElementType Unitialized } - public abstract class VerificationElement - { + public abstract class VerificationElement { public abstract VerificationElementType Type { get; } } - public class SimpleVerificationElement : VerificationElement - { + public class SimpleVerificationElement : VerificationElement { public override VerificationElementType Type { get; } - public SimpleVerificationElement(VerificationElementType type) - { + public SimpleVerificationElement(VerificationElementType type) { type.CheckInAndThrow(nameof(type), VerificationElementType.Top, VerificationElementType.Integer, VerificationElementType.Float, VerificationElementType.Long, VerificationElementType.Double, VerificationElementType.Null, VerificationElementType.UnitializedThis); this.Type = type; } } - public class ObjectVerificationElement : VerificationElement - { + public class ObjectVerificationElement : VerificationElement { public override VerificationElementType Type => VerificationElementType.Object; public ClassName ObjectClass { get; set; } } - public class UninitializedVerificationElement : VerificationElement - { + public class UninitializedVerificationElement : VerificationElement { public override VerificationElementType Type => VerificationElementType.Unitialized; public ushort NewInstructionOffset { get; set; } } - public enum FrameType - { + public enum FrameType { Same, SameLocals1StackItem, Chop, @@ -63,8 +54,7 @@ public enum FrameType Full } - public class StackMapFrame - { + public class StackMapFrame { public FrameType Type { get; set; } public ushort OffsetDelta { get; set; } @@ -78,11 +68,9 @@ public class StackMapFrame public List Entries { get; set; } = new List(); - internal static void WriteVerificationElement(Stream stream, ClassWriterState writerState, VerificationElement verificationElement) - { + internal static void WriteVerificationElement(Stream stream, ClassWriterState writerState, VerificationElement verificationElement) { stream.WriteByte((byte) verificationElement.Type); - switch (verificationElement) - { + switch (verificationElement) { case ObjectVerificationElement objectVerificationElement: Binary.BigEndian.Write(stream, writerState.ConstantPool.Find( @@ -91,15 +79,12 @@ internal static void WriteVerificationElement(Stream stream, ClassWriterState wr case UninitializedVerificationElement uninitializedVerificationElement: Binary.BigEndian.Write(stream, uninitializedVerificationElement.NewInstructionOffset); break; - case SimpleVerificationElement _: - break; - default: - throw new ArgumentOutOfRangeException(nameof(verificationElement)); + case SimpleVerificationElement _: break; + default: throw new ArgumentOutOfRangeException(nameof(verificationElement)); } } - internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) - { + internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) { MemoryStream attributeDataStream = new MemoryStream(); if (this.Entries.Count > ushort.MaxValue) @@ -107,24 +92,21 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope Binary.BigEndian.Write(attributeDataStream, (ushort) this.Entries.Count); - foreach (StackMapFrame entry in this.Entries) - { - switch (entry.Type) - { + foreach (StackMapFrame entry in this.Entries) { + switch (entry.Type) { case FrameType.Same: if (entry.OffsetDelta < 64) attributeDataStream.WriteByte((byte) entry.OffsetDelta); - else - { + else { attributeDataStream.WriteByte(251); Binary.BigEndian.Write(attributeDataStream, entry.OffsetDelta); } + break; case FrameType.SameLocals1StackItem: if (entry.OffsetDelta < 64) attributeDataStream.WriteByte((byte) (entry.OffsetDelta + 64)); - else - { + else { attributeDataStream.WriteByte(247); Binary.BigEndian.Write(attributeDataStream, entry.OffsetDelta); } @@ -168,8 +150,7 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope foreach (VerificationElement verificationElement in entry.Stack) WriteVerificationElement(attributeDataStream, writerState, verificationElement); break; - default: - throw new ArgumentOutOfRangeException(nameof(entry.Type)); + default: throw new ArgumentOutOfRangeException(nameof(entry.Type)); } } @@ -177,8 +158,7 @@ internal override byte[] Save(ClassWriterState writerState, AttributeScope scope } } - internal class StackMapTableAttributeFactory : ICustomAttributeFactory - { + internal class StackMapTableAttributeFactory : ICustomAttributeFactory { private static StackMapTableAttribute.VerificationElement ReadVerificationElement(Stream stream, ClassReaderState readerState) { StackMapTableAttribute.VerificationElementType verificationElementType = (StackMapTableAttribute.VerificationElementType) stream.ReadByteFully(); switch (verificationElementType) { @@ -196,78 +176,61 @@ private static StackMapTableAttribute.VerificationElement ReadVerificationElemen } } - public StackMapTableAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) - { + public StackMapTableAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) { StackMapTableAttribute attribute = new StackMapTableAttribute(); ushort stackMapTableSize = Binary.BigEndian.ReadUInt16(attributeDataStream); attribute.Entries.Capacity = stackMapTableSize; - for (int i = 0; i < stackMapTableSize; i++) - { + for (int i = 0; i < stackMapTableSize; i++) { StackMapTableAttribute.StackMapFrame stackMapFrame; byte frameTypeByte = attributeDataStream.ReadByteFully(); - if (frameTypeByte < 64) - { - stackMapFrame = new StackMapTableAttribute.StackMapFrame - { + if (frameTypeByte < 64) { + stackMapFrame = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.Same, OffsetDelta = frameTypeByte }; } - else if (frameTypeByte < 128) - { - stackMapFrame = new StackMapTableAttribute.StackMapFrame - { + else if (frameTypeByte < 128) { + stackMapFrame = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.SameLocals1StackItem, OffsetDelta = (ushort) (frameTypeByte - 64) }; stackMapFrame.Stack.Add(ReadVerificationElement(attributeDataStream, readerState)); } - else if (frameTypeByte == 247) - { - stackMapFrame = new StackMapTableAttribute.StackMapFrame - { + else if (frameTypeByte == 247) { + stackMapFrame = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.SameLocals1StackItem, OffsetDelta = Binary.BigEndian.ReadUInt16(attributeDataStream) }; stackMapFrame.Stack.Add(ReadVerificationElement(attributeDataStream, readerState)); } - else if (frameTypeByte < 251) - { - stackMapFrame = new StackMapTableAttribute.StackMapFrame - { + else if (frameTypeByte < 251) { + stackMapFrame = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.Chop, OffsetDelta = Binary.BigEndian.ReadUInt16(attributeDataStream), ChopK = (byte) (251 - frameTypeByte) }; } - else if (frameTypeByte == 251) - { - stackMapFrame = new StackMapTableAttribute.StackMapFrame - { + else if (frameTypeByte == 251) { + stackMapFrame = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.Same, OffsetDelta = Binary.BigEndian.ReadUInt16(attributeDataStream) }; } - else if (frameTypeByte < 255) - { - stackMapFrame = new StackMapTableAttribute.StackMapFrame - { + else if (frameTypeByte < 255) { + stackMapFrame = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.Append, OffsetDelta = Binary.BigEndian.ReadUInt16(attributeDataStream) }; - for (int j = 0; j < frameTypeByte - 251; j++) - { + for (int j = 0; j < frameTypeByte - 251; j++) { stackMapFrame.Locals.Add(ReadVerificationElement(attributeDataStream, readerState)); } } - else if (frameTypeByte == 255) - { - stackMapFrame = new StackMapTableAttribute.StackMapFrame - { + else if (frameTypeByte == 255) { + stackMapFrame = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.Full, OffsetDelta = Binary.BigEndian.ReadUInt16(attributeDataStream) }; @@ -288,4 +251,4 @@ public StackMapTableAttribute Parse(Stream attributeDataStream, uint attributeDa return attribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/SyntheticAttribute.cs b/JavaAsm/CustomAttributes/SyntheticAttribute.cs index 6a91057..4e922bf 100644 --- a/JavaAsm/CustomAttributes/SyntheticAttribute.cs +++ b/JavaAsm/CustomAttributes/SyntheticAttribute.cs @@ -1,15 +1,12 @@ using System.IO; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes -{ - public class SyntheticAttribute : CustomAttribute - { +namespace JavaAsm.CustomAttributes { + public class SyntheticAttribute : CustomAttribute { internal override byte[] Save(ClassWriterState writerState, AttributeScope scope) => new byte[0]; } - internal class SyntheticAttributeFactory : ICustomAttributeFactory - { + internal class SyntheticAttributeFactory : ICustomAttributeFactory { public SyntheticAttribute Parse(Stream attributeDataStream, uint attributeDataLength, ClassReaderState readerState, AttributeScope scope) => new SyntheticAttribute(); } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/CatchTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/CatchTarget.cs index 0a9a85d..b4102ac 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/CatchTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/CatchTarget.cs @@ -2,21 +2,17 @@ using BinaryEncoding; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class CatchTarget : TypeAnnotationTarget - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class CatchTarget : TypeAnnotationTarget { public ushort ExceptionTableIndex { get; set; } public override TargetTypeKind TargetTypeKind => TargetTypeKind.Catch; - internal override void Write(Stream stream, ClassWriterState writerState) - { + internal override void Write(Stream stream, ClassWriterState writerState) { Binary.BigEndian.Write(stream, this.ExceptionTableIndex); } - internal override void Read(Stream stream, ClassReaderState readerState) - { + internal override void Read(Stream stream, ClassReaderState readerState) { this.ExceptionTableIndex = Binary.BigEndian.ReadUInt16(stream); } } diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/EmptyTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/EmptyTarget.cs index d6bd0ef..5ac7e63 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/EmptyTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/EmptyTarget.cs @@ -1,10 +1,8 @@ using System.IO; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class EmptyTarget : TypeAnnotationTarget - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class EmptyTarget : TypeAnnotationTarget { public override TargetTypeKind TargetTypeKind => TargetTypeKind.Empty; internal override void Write(Stream stream, ClassWriterState writerState) { } diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/FormalParameterTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/FormalParameterTarget.cs index da2fae4..d84ddd0 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/FormalParameterTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/FormalParameterTarget.cs @@ -2,21 +2,17 @@ using JavaAsm.Helpers; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class FormalParameterTarget : TypeAnnotationTarget - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class FormalParameterTarget : TypeAnnotationTarget { public byte FormalParameterIndex { get; set; } public override TargetTypeKind TargetTypeKind => TargetTypeKind.FormalParameter; - internal override void Write(Stream stream, ClassWriterState writerState) - { + internal override void Write(Stream stream, ClassWriterState writerState) { stream.WriteByte(this.FormalParameterIndex); } - internal override void Read(Stream stream, ClassReaderState readerState) - { + internal override void Read(Stream stream, ClassReaderState readerState) { this.FormalParameterIndex = stream.ReadByteFully(); } } diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/LocalvarTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/LocalvarTarget.cs index c6caa98..fca7853 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/LocalvarTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/LocalvarTarget.cs @@ -4,12 +4,9 @@ using BinaryEncoding; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class LocalvarTarget : TypeAnnotationTarget - { - public class TableEntry - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class LocalvarTarget : TypeAnnotationTarget { + public class TableEntry { public ushort StartPc { get; set; } public ushort Length { get; set; } @@ -21,27 +18,22 @@ public class TableEntry public override TargetTypeKind TargetTypeKind => TargetTypeKind.Localvar; - internal override void Write(Stream stream, ClassWriterState writerState) - { + internal override void Write(Stream stream, ClassWriterState writerState) { if (this.Table.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.Table.Count), $"Table is too big: {this.Table.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(stream, (ushort) this.Table.Count); - foreach (TableEntry entry in this.Table) - { + foreach (TableEntry entry in this.Table) { Binary.BigEndian.Write(stream, entry.StartPc); Binary.BigEndian.Write(stream, entry.Length); Binary.BigEndian.Write(stream, entry.Index); } } - internal override void Read(Stream stream, ClassReaderState readerState) - { + internal override void Read(Stream stream, ClassReaderState readerState) { ushort tableSize = Binary.BigEndian.ReadUInt16(stream); this.Table.Capacity = tableSize; - for (int i = 0; i < tableSize; i++) - { - this.Table.Add(new TableEntry - { + for (int i = 0; i < tableSize; i++) { + this.Table.Add(new TableEntry { StartPc = Binary.BigEndian.ReadUInt16(stream), Length = Binary.BigEndian.ReadUInt16(stream), Index = Binary.BigEndian.ReadUInt16(stream) diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/OffsetTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/OffsetTarget.cs index a7303c8..1535767 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/OffsetTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/OffsetTarget.cs @@ -2,21 +2,17 @@ using BinaryEncoding; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class OffsetTarget : TypeAnnotationTarget - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class OffsetTarget : TypeAnnotationTarget { public ushort Offset { get; set; } public override TargetTypeKind TargetTypeKind => TargetTypeKind.Offset; - internal override void Write(Stream stream, ClassWriterState writerState) - { + internal override void Write(Stream stream, ClassWriterState writerState) { Binary.BigEndian.Write(stream, this.Offset); } - internal override void Read(Stream stream, ClassReaderState readerState) - { + internal override void Read(Stream stream, ClassReaderState readerState) { this.Offset = Binary.BigEndian.ReadUInt16(stream); } } diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/SupertypeTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/SupertypeTarget.cs index 6fd6d97..77508b4 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/SupertypeTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/SupertypeTarget.cs @@ -2,21 +2,17 @@ using BinaryEncoding; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class SupertypeTarget : TypeAnnotationTarget - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class SupertypeTarget : TypeAnnotationTarget { public ushort SupertypeIndex { get; set; } public override TargetTypeKind TargetTypeKind => TargetTypeKind.Supertype; - internal override void Write(Stream stream, ClassWriterState writerState) - { + internal override void Write(Stream stream, ClassWriterState writerState) { Binary.BigEndian.Write(stream, this.SupertypeIndex); } - internal override void Read(Stream stream, ClassReaderState readerState) - { + internal override void Read(Stream stream, ClassReaderState readerState) { this.SupertypeIndex = Binary.BigEndian.ReadUInt16(stream); } } diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TargetType.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TargetType.cs index 9284b15..7a24808 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TargetType.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TargetType.cs @@ -1,7 +1,5 @@ -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public enum TargetType - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public enum TargetType { // Type in ... GenericClassOrInterfaceDeclaration = 0x00, diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TargetTypeKind.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TargetTypeKind.cs index 2bdd4d6..4d14fb1 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TargetTypeKind.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TargetTypeKind.cs @@ -1,7 +1,5 @@ -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public enum TargetTypeKind - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public enum TargetTypeKind { TypeParameter, Supertype, TypeParameterBound, diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/ThrowsTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/ThrowsTarget.cs index 24ec1aa..e7766e7 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/ThrowsTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/ThrowsTarget.cs @@ -2,21 +2,17 @@ using BinaryEncoding; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class ThrowsTarget : TypeAnnotationTarget - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class ThrowsTarget : TypeAnnotationTarget { public ushort ThrowsTypeIndex { get; set; } public override TargetTypeKind TargetTypeKind => TargetTypeKind.Throws; - internal override void Write(Stream stream, ClassWriterState writerState) - { + internal override void Write(Stream stream, ClassWriterState writerState) { Binary.BigEndian.Write(stream, this.ThrowsTypeIndex); } - internal override void Read(Stream stream, ClassReaderState readerState) - { + internal override void Read(Stream stream, ClassReaderState readerState) { this.ThrowsTypeIndex = Binary.BigEndian.ReadUInt16(stream); } } diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationNode.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationNode.cs index 8b7eff7..db39010 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationNode.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationNode.cs @@ -7,10 +7,8 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class TypeAnnotationNode - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class TypeAnnotationNode { public TargetType TargetType { get; set; } public TypeAnnotationTarget Target { get; set; } @@ -19,8 +17,7 @@ public class TypeAnnotationNode public TypeDescriptor Type { get; set; } - public class ElementValuePair - { + public class ElementValuePair { public string ElementName { get; set; } public ElementValue Value { get; set; } @@ -28,10 +25,8 @@ public class ElementValuePair public List ElementValuePairs { get; set; } = new List(); - internal static TypeAnnotationNode Parse(Stream stream, ClassReaderState readerState, AttributeScope scope) - { - TypeAnnotationNode typeAnnotation = new TypeAnnotationNode - { + internal static TypeAnnotationNode Parse(Stream stream, ClassReaderState readerState, AttributeScope scope) { + TypeAnnotationNode typeAnnotation = new TypeAnnotationNode { TargetType = (TargetType) stream.ReadByteFully() }; switch (typeAnnotation.TargetType) { @@ -88,20 +83,16 @@ internal static TypeAnnotationNode Parse(Stream stream, ClassReaderState readerS ushort elementValuePairsCount = Binary.BigEndian.ReadUInt16(stream); typeAnnotation.ElementValuePairs.Capacity = elementValuePairsCount; for (int i = 0; i < elementValuePairsCount; i++) - typeAnnotation.ElementValuePairs.Add(new ElementValuePair - { - ElementName = readerState.ConstantPool - .GetEntry(Binary.BigEndian.ReadUInt16(stream)).String, + typeAnnotation.ElementValuePairs.Add(new ElementValuePair { + ElementName = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String, Value = ElementValue.Parse(stream, readerState) }); return typeAnnotation; } - internal void Write(Stream stream, ClassWriterState writerState, AttributeScope scope) - { + internal void Write(Stream stream, ClassWriterState writerState, AttributeScope scope) { stream.WriteByte((byte) this.TargetType); - switch (this.TargetType) - { + switch (this.TargetType) { case TargetType.GenericClassOrInterfaceDeclaration when this.Target.TargetTypeKind == TargetTypeKind.TypeParameter && scope == AttributeScope.Class: case TargetType.GenericMethodOrConstructorDeclaration when this.Target.TargetTypeKind == TargetTypeKind.TypeParameter && scope == AttributeScope.Method: case TargetType.ExtendsOrImplements when this.Target.TargetTypeKind == TargetTypeKind.Supertype && scope == AttributeScope.Class: @@ -126,8 +117,7 @@ internal void Write(Stream stream, ClassWriterState writerState, AttributeScope case TargetType.ArgumentForGenericMethodReferenceExpressionIdentifier when this.Target.TargetTypeKind == TargetTypeKind.TypeArgument && scope == AttributeScope.Code: this.Target.Write(stream, writerState); break; - default: - throw new ArgumentOutOfRangeException(nameof(this.TargetType)); + default: throw new ArgumentOutOfRangeException(nameof(this.TargetType)); } this.TypePath.Write(stream, writerState); @@ -136,12 +126,11 @@ internal void Write(Stream stream, ClassWriterState writerState, AttributeScope throw new ArgumentOutOfRangeException(nameof(this.ElementValuePairs.Count), $"Too many ElementValues: {this.ElementValuePairs.Count} > {ushort.MaxValue}"); Binary.BigEndian.Write(stream, (ushort) this.ElementValuePairs.Count); - foreach (ElementValuePair elementValuePair in this.ElementValuePairs) - { + foreach (ElementValuePair elementValuePair in this.ElementValuePairs) { Binary.BigEndian.Write(stream, writerState.ConstantPool.Find(new Utf8Entry(elementValuePair.ElementName))); elementValuePair.Value.Write(stream, writerState); } } } -} +} \ No newline at end of file diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationTarget.cs index d901089..53eaeac 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypeAnnotationTarget.cs @@ -1,10 +1,8 @@ using System.IO; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public abstract class TypeAnnotationTarget - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public abstract class TypeAnnotationTarget { public abstract TargetTypeKind TargetTypeKind { get; } internal abstract void Write(Stream stream, ClassWriterState writerState); diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypeArgumentTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypeArgumentTarget.cs index 1da5498..f729308 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypeArgumentTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypeArgumentTarget.cs @@ -3,24 +3,20 @@ using JavaAsm.Helpers; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class TypeArgumentTarget : TypeAnnotationTarget - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class TypeArgumentTarget : TypeAnnotationTarget { public ushort Offset { get; set; } public byte TypeArgumentIndex { get; set; } public override TargetTypeKind TargetTypeKind => TargetTypeKind.TypeArgument; - internal override void Write(Stream stream, ClassWriterState writerState) - { + internal override void Write(Stream stream, ClassWriterState writerState) { Binary.BigEndian.Write(stream, this.Offset); stream.WriteByte(this.TypeArgumentIndex); } - internal override void Read(Stream stream, ClassReaderState readerState) - { + internal override void Read(Stream stream, ClassReaderState readerState) { this.Offset = Binary.BigEndian.ReadUInt16(stream); this.TypeArgumentIndex = stream.ReadByteFully(); } diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterBoundTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterBoundTarget.cs index 137b819..196a16c 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterBoundTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterBoundTarget.cs @@ -2,24 +2,20 @@ using JavaAsm.Helpers; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class TypeParameterBoundTarget : TypeAnnotationTarget - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class TypeParameterBoundTarget : TypeAnnotationTarget { public byte TypeParameterIndex { get; set; } public byte BoundIndex { get; set; } public override TargetTypeKind TargetTypeKind => TargetTypeKind.TypeParameterBound; - internal override void Write(Stream stream, ClassWriterState writerState) - { + internal override void Write(Stream stream, ClassWriterState writerState) { stream.WriteByte(this.TypeParameterIndex); stream.WriteByte(this.BoundIndex); } - internal override void Read(Stream stream, ClassReaderState readerState) - { + internal override void Read(Stream stream, ClassReaderState readerState) { this.TypeParameterIndex = stream.ReadByteFully(); this.BoundIndex = stream.ReadByteFully(); } diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterTarget.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterTarget.cs index 41efdf1..b384f25 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterTarget.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypeParameterTarget.cs @@ -2,21 +2,17 @@ using JavaAsm.Helpers; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class TypeParameterTarget : TypeAnnotationTarget - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class TypeParameterTarget : TypeAnnotationTarget { public byte TypeParameterIndex { get; set; } public override TargetTypeKind TargetTypeKind => TargetTypeKind.TypeParameter; - internal override void Write(Stream stream, ClassWriterState writerState) - { + internal override void Write(Stream stream, ClassWriterState writerState) { stream.WriteByte(this.TypeParameterIndex); } - internal override void Read(Stream stream, ClassReaderState readerState) - { + internal override void Read(Stream stream, ClassReaderState readerState) { this.TypeParameterIndex = stream.ReadByteFully(); } } diff --git a/JavaAsm/CustomAttributes/TypeAnnotation/TypePath.cs b/JavaAsm/CustomAttributes/TypeAnnotation/TypePath.cs index 6c6fb3f..4c2904a 100644 --- a/JavaAsm/CustomAttributes/TypeAnnotation/TypePath.cs +++ b/JavaAsm/CustomAttributes/TypeAnnotation/TypePath.cs @@ -4,20 +4,16 @@ using JavaAsm.Helpers; using JavaAsm.IO; -namespace JavaAsm.CustomAttributes.TypeAnnotation -{ - public class TypePath - { - public enum TypePathKind - { +namespace JavaAsm.CustomAttributes.TypeAnnotation { + public class TypePath { + public enum TypePathKind { DeeperInArray, DeeperInNested, Wildcard, Type } - public class PathPart - { + public class PathPart { public TypePathKind TypePathKind { get; set; } public byte TypeArgumentIndex { get; set; } @@ -25,27 +21,22 @@ public class PathPart public List Path { get; set; } = new List(); - internal void Read(Stream stream, ClassReaderState classReaderState) - { + internal void Read(Stream stream, ClassReaderState classReaderState) { byte pathSize = stream.ReadByteFully(); this.Path.Capacity = pathSize; - for (int i = 0; i < pathSize; i++) - { - this.Path.Add(new PathPart - { + for (int i = 0; i < pathSize; i++) { + this.Path.Add(new PathPart { TypePathKind = (TypePathKind) stream.ReadByteFully(), TypeArgumentIndex = stream.ReadByteFully() }); } } - internal void Write(Stream stream, ClassWriterState writerState) - { + internal void Write(Stream stream, ClassWriterState writerState) { if (this.Path.Count > byte.MaxValue) throw new ArgumentOutOfRangeException(nameof(this.Path.Count), $"Path is too big: {this.Path.Count} > {byte.MaxValue}"); stream.WriteByte((byte) this.Path.Count); - foreach (PathPart part in this.Path) - { + foreach (PathPart part in this.Path) { stream.WriteByte((byte) part.TypePathKind); stream.WriteByte(part.TypeArgumentIndex); } diff --git a/JavaAsm/FieldNode.cs b/JavaAsm/FieldNode.cs index 68bd93d..d95670f 100644 --- a/JavaAsm/FieldNode.cs +++ b/JavaAsm/FieldNode.cs @@ -5,13 +5,11 @@ using JavaAsm.CustomAttributes.Annotation; using JavaAsm.IO; -namespace JavaAsm -{ +namespace JavaAsm { /// /// Field node /// - public class FieldNode - { + public class FieldNode { /// /// Owner class /// @@ -69,8 +67,7 @@ public class FieldNode /// /// Name of annotation /// null, if attribute does not exist or AttributeNode if exists - private AttributeNode GetAttribute(string name) - { + private AttributeNode GetAttribute(string name) { AttributeNode attribute = this.Attributes.FirstOrDefault(a => a.Name == name); if (attribute != null) this.Attributes.Remove(attribute); @@ -81,8 +78,7 @@ private AttributeNode GetAttribute(string name) /// Parses field annotations to fill up information /// /// Class reader state - internal void Parse(ClassReaderState readerState) - { + internal void Parse(ClassReaderState readerState) { this.Signature = (GetAttribute(PredefinedAttributeNames.Signature)?.ParsedAttribute as SignatureAttribute)?.Value; { AttributeNode attribute = GetAttribute(PredefinedAttributeNames.RuntimeInvisibleAnnotations); @@ -104,76 +100,56 @@ internal void Parse(ClassReaderState readerState) /// Saves method information to annotations /// /// Class writer state - internal void Save(ClassWriterState writerState) - { - if (this.Signature != null) - { + internal void Save(ClassWriterState writerState) { + if (this.Signature != null) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Signature)) - throw new Exception( - $"{PredefinedAttributeNames.Signature} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + throw new Exception($"{PredefinedAttributeNames.Signature} attribute is already presented on field"); + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Signature, - ParsedAttribute = new SignatureAttribute - { + ParsedAttribute = new SignatureAttribute { Value = this.Signature } }); } - if (this.InvisibleAnnotations != null && this.InvisibleAnnotations.Count > 0) - { + if (this.InvisibleAnnotations != null && this.InvisibleAnnotations.Count > 0) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeInvisibleAnnotations)) - throw new Exception( - $"{PredefinedAttributeNames.RuntimeInvisibleAnnotations} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + throw new Exception($"{PredefinedAttributeNames.RuntimeInvisibleAnnotations} attribute is already presented on field"); + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeInvisibleAnnotations, - ParsedAttribute = new RuntimeInvisibleAnnotationsAttribute - { + ParsedAttribute = new RuntimeInvisibleAnnotationsAttribute { Annotations = this.InvisibleAnnotations } }); } - if (this.VisibleAnnotations != null && this.VisibleAnnotations.Count > 0) - { + if (this.VisibleAnnotations != null && this.VisibleAnnotations.Count > 0) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.RuntimeVisibleAnnotations)) - throw new Exception( - $"{PredefinedAttributeNames.RuntimeVisibleAnnotations} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + throw new Exception($"{PredefinedAttributeNames.RuntimeVisibleAnnotations} attribute is already presented on field"); + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.RuntimeVisibleAnnotations, - ParsedAttribute = new RuntimeVisibleAnnotationsAttribute - { + ParsedAttribute = new RuntimeVisibleAnnotationsAttribute { Annotations = this.VisibleAnnotations } }); } - if (this.ConstantValue != null) - { + if (this.ConstantValue != null) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.ConstantValue)) - throw new Exception( - $"{PredefinedAttributeNames.ConstantValue} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + throw new Exception($"{PredefinedAttributeNames.ConstantValue} attribute is already presented on field"); + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.ConstantValue, - ParsedAttribute = new ConstantValueAttribute - { + ParsedAttribute = new ConstantValueAttribute { Value = this.ConstantValue } }); } // ReSharper disable once InvertIf - if (this.IsDeprecated) - { + if (this.IsDeprecated) { if (this.Attributes.Any(x => x.Name == PredefinedAttributeNames.Deprecated)) - throw new Exception( - $"{PredefinedAttributeNames.Deprecated} attribute is already presented on field"); - this.Attributes.Add(new AttributeNode - { + throw new Exception($"{PredefinedAttributeNames.Deprecated} attribute is already presented on field"); + this.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.Deprecated, ParsedAttribute = new DeprecatedAttribute() }); @@ -181,8 +157,7 @@ internal void Save(ClassWriterState writerState) } /// - public override string ToString() - { + public override string ToString() { return $"{AccessModifiersExtensions.ToString(this.Access)} {this.Descriptor} {this.Name}"; } } diff --git a/JavaAsm/Helpers/ModifiedUtf8Helper.cs b/JavaAsm/Helpers/ModifiedUtf8Helper.cs index c5dc10d..3c3782b 100644 --- a/JavaAsm/Helpers/ModifiedUtf8Helper.cs +++ b/JavaAsm/Helpers/ModifiedUtf8Helper.cs @@ -1,37 +1,30 @@ using System; -namespace JavaAsm.Helpers -{ - public static class ModifiedUtf8Helper - { - public static byte[] Encode(string value) - { +namespace JavaAsm.Helpers { + public static class ModifiedUtf8Helper { + public static byte[] Encode(string value) { int offset = 0; byte[] buffer = new byte[GetBytesCount(value)]; - foreach (char c in value) - { + foreach (char c in value) { if (c != 0 && c <= 127) - buffer[offset++] = (byte)c; - else if (c <= 2047) - { - buffer[offset++] = (byte)(0xc0 | (0x1f & (c >> 6))); - buffer[offset++] = (byte)(0x80 | (0x3f & c)); + buffer[offset++] = (byte) c; + else if (c <= 2047) { + buffer[offset++] = (byte) (0xc0 | (0x1f & (c >> 6))); + buffer[offset++] = (byte) (0x80 | (0x3f & c)); } - else - { - buffer[offset++] = (byte)(0xe0 | (0x0f & (c >> 12))); - buffer[offset++] = (byte)(0x80 | (0x3f & (c >> 6))); - buffer[offset++] = (byte)(0x80 | (0x3f & c)); + else { + buffer[offset++] = (byte) (0xe0 | (0x0f & (c >> 12))); + buffer[offset++] = (byte) (0x80 | (0x3f & (c >> 6))); + buffer[offset++] = (byte) (0x80 | (0x3f & c)); } } + return buffer; } - public static ushort GetBytesCount(string value) - { + public static ushort GetBytesCount(string value) { int bytesCount = 0; - foreach (char c in value) - { + foreach (char c in value) { if (c != 0 && c <= 127) bytesCount++; else if (c <= 2047) @@ -42,40 +35,36 @@ public static ushort GetBytesCount(string value) if (bytesCount > ushort.MaxValue) throw new FormatException("String more than 65535 UTF bytes long"); } + return (ushort) bytesCount; } - public static string Decode(byte[] data) - { + public static string Decode(byte[] data) { int length = data.Length; char[] result = new char[length]; int count = 0; int numberOfChars = 0; - while (count < length) - { + while (count < length) { if ((result[numberOfChars] = (char) data[count++]) < '\u0080') numberOfChars++; - else - { + else { int a; - if (((a = result[numberOfChars]) & 0xe0) == 0xc0) - { + if (((a = result[numberOfChars]) & 0xe0) == 0xc0) { if (count >= length) throw new FormatException($"Bad second byte at {count}"); int b = data[count++]; if ((b & 0xC0) != 0x80) throw new FormatException($"Bad second byte at {count - 1}"); - result[numberOfChars++] = (char)(((a & 0x1F) << 6) | (b & 0x3F)); + result[numberOfChars++] = (char) (((a & 0x1F) << 6) | (b & 0x3F)); } - else if ((a & 0xf0) == 0xe0) - { + else if ((a & 0xf0) == 0xe0) { if (count + 1 >= length) throw new FormatException($"Bad third byte at {count + 1}"); int b = data[count++]; int c = data[count++]; if ((b & 0xC0) != 0x80 || (c & 0xC0) != 0x80) throw new FormatException($"Bad second or third byte at {count - 2}"); - result[numberOfChars++] = (char)(((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F)); + result[numberOfChars++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F)); } else throw new FormatException($"Bad byte at {count - 1}"); @@ -85,4 +74,4 @@ public static string Decode(byte[] data) return new string(result, 0, numberOfChars); } } -} +} \ No newline at end of file diff --git a/JavaAsm/Helpers/ReadCountStream.cs b/JavaAsm/Helpers/ReadCountStream.cs index bc236dd..1423b95 100644 --- a/JavaAsm/Helpers/ReadCountStream.cs +++ b/JavaAsm/Helpers/ReadCountStream.cs @@ -1,27 +1,22 @@ using System; using System.IO; -namespace JavaAsm.Helpers -{ - public class ReadWriteCountStream : Stream - { +namespace JavaAsm.Helpers { + public class ReadWriteCountStream : Stream { private readonly Stream baseStream; public long ReadBytes { get; private set; } public long WrittenBytes { get; private set; } - public ReadWriteCountStream(Stream baseStream) - { + public ReadWriteCountStream(Stream baseStream) { this.baseStream = baseStream; } - public override void Flush() - { + public override void Flush() { this.baseStream.Flush(); } - public override int Read(byte[] buffer, int offset, int count) - { + public override int Read(byte[] buffer, int offset, int count) { int result = this.baseStream.Read(buffer, offset, count); this.ReadBytes += Math.Max(0, result); return result; @@ -31,8 +26,7 @@ public override int Read(byte[] buffer, int offset, int count) public override void SetLength(long value) => throw new InvalidOperationException(); - public override void Write(byte[] buffer, int offset, int count) - { + public override void Write(byte[] buffer, int offset, int count) { this.baseStream.Write(buffer, offset, count); this.WrittenBytes += count; } @@ -45,10 +39,9 @@ public override void Write(byte[] buffer, int offset, int count) public override long Length => this.baseStream.Length; - public override long Position - { + public override long Position { get => this.baseStream.Position; set => this.baseStream.Position = value; } } -} +} \ No newline at end of file diff --git a/JavaAsm/IDescriptor.cs b/JavaAsm/IDescriptor.cs index 16c12d7..449c500 100644 --- a/JavaAsm/IDescriptor.cs +++ b/JavaAsm/IDescriptor.cs @@ -1,7 +1,7 @@ -namespace JavaAsm -{ +namespace JavaAsm { /// /// Common interface for all descriptors /// - public interface IDescriptor { } + public interface IDescriptor { + } } \ No newline at end of file diff --git a/JavaAsm/IO/ClassFile.cs b/JavaAsm/IO/ClassFile.cs index 857ca64..ced1c4b 100644 --- a/JavaAsm/IO/ClassFile.cs +++ b/JavaAsm/IO/ClassFile.cs @@ -3,26 +3,20 @@ using BinaryEncoding; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.IO -{ - public static class ClassFile - { +namespace JavaAsm.IO { + public static class ClassFile { private const uint Magic = 0xCAFEBABE; - internal static AttributeNode ParseAttribute(Stream stream, ClassReaderState state, AttributeScope scope) - { - AttributeNode attribute = new AttributeNode - { + internal static AttributeNode ParseAttribute(Stream stream, ClassReaderState state, AttributeScope scope) { + AttributeNode attribute = new AttributeNode { Name = state.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String }; attribute.Parse(stream, scope, state); return attribute; } - private static FieldNode ParseField(Stream stream, ClassReaderState state) - { - FieldNode fieldNode = new FieldNode - { + private static FieldNode ParseField(Stream stream, ClassReaderState state) { + FieldNode fieldNode = new FieldNode { Owner = state.ClassNode, Access = (FieldAccessModifiers) Binary.BigEndian.ReadUInt16(stream), @@ -36,13 +30,11 @@ private static FieldNode ParseField(Stream stream, ClassReaderState state) return fieldNode; } - private static MethodNode ParseMethod(Stream stream, ClassReaderState state) - { - MethodNode methodNode = new MethodNode - { + private static MethodNode ParseMethod(Stream stream, ClassReaderState state) { + MethodNode methodNode = new MethodNode { Owner = state.ClassNode, - Access = (MethodAccessModifiers)Binary.BigEndian.ReadUInt16(stream), + Access = (MethodAccessModifiers) Binary.BigEndian.ReadUInt16(stream), Name = state.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String, Descriptor = MethodDescriptor.Parse(state.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(stream)).String) }; @@ -53,8 +45,7 @@ private static MethodNode ParseMethod(Stream stream, ClassReaderState state) return methodNode; } - public static ClassNode ParseClass(Stream stream) - { + public static ClassNode ParseClass(Stream stream) { ClassReaderState state = new ClassReaderState(); ClassNode result = new ClassNode(); state.ClassNode = result; @@ -102,8 +93,7 @@ public static ClassNode ParseClass(Stream stream) return result; } - internal static void WriteAttribute(Stream stream, AttributeNode attribute, ClassWriterState state, AttributeScope scope) - { + internal static void WriteAttribute(Stream stream, AttributeNode attribute, ClassWriterState state, AttributeScope scope) { Binary.BigEndian.Write(stream, state.ConstantPool.Find(new Utf8Entry(attribute.Name))); attribute.Data = attribute.ParsedAttribute?.Save(state, scope) ?? attribute.Data; if (attribute.Data.LongLength > uint.MaxValue) @@ -112,8 +102,7 @@ internal static void WriteAttribute(Stream stream, AttributeNode attribute, Clas stream.Write(attribute.Data, 0, attribute.Data.Length); } - private static void WriteField(Stream stream, FieldNode fieldNode, ClassWriterState state) - { + private static void WriteField(Stream stream, FieldNode fieldNode, ClassWriterState state) { Binary.BigEndian.Write(stream, (ushort) fieldNode.Access); Binary.BigEndian.Write(stream, state.ConstantPool.Find(new Utf8Entry(fieldNode.Name))); Binary.BigEndian.Write(stream, state.ConstantPool.Find(new Utf8Entry(fieldNode.Descriptor.ToString()))); @@ -124,27 +113,24 @@ private static void WriteField(Stream stream, FieldNode fieldNode, ClassWriterSt WriteAttribute(stream, attriute, state, AttributeScope.Field); } - private static void WriteMethod(Stream stream, MethodNode methodNode, ClassWriterState state) - { - Binary.BigEndian.Write(stream, (ushort)methodNode.Access); + private static void WriteMethod(Stream stream, MethodNode methodNode, ClassWriterState state) { + Binary.BigEndian.Write(stream, (ushort) methodNode.Access); Binary.BigEndian.Write(stream, state.ConstantPool.Find(new Utf8Entry(methodNode.Name))); Binary.BigEndian.Write(stream, state.ConstantPool.Find(new Utf8Entry(methodNode.Descriptor.ToString()))); if (methodNode.Attributes.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(methodNode.Attributes.Count), $"Too many attributes: {methodNode.Attributes.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(stream, (ushort)methodNode.Attributes.Count); + Binary.BigEndian.Write(stream, (ushort) methodNode.Attributes.Count); foreach (AttributeNode attriute in methodNode.Attributes) WriteAttribute(stream, attriute, state, AttributeScope.Method); } - public static void WriteClass(Stream stream, ClassNode classNode) - { + public static void WriteClass(Stream stream, ClassNode classNode) { Binary.BigEndian.Write(stream, Magic); Binary.BigEndian.Write(stream, classNode.MinorVersion); Binary.BigEndian.Write(stream, (ushort) classNode.MajorVersion); MemoryStream afterConstantPoolDataStream = new MemoryStream(); ConstantPool constantPool = new ConstantPool(); - ClassWriterState state = new ClassWriterState - { + ClassWriterState state = new ClassWriterState { ClassNode = classNode, ConstantPool = constantPool }; @@ -172,13 +158,13 @@ public static void WriteClass(Stream stream, ClassNode classNode) if (classNode.Methods.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(classNode.Methods.Count), $"Too many methods: {classNode.Methods.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort)classNode.Methods.Count); + Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort) classNode.Methods.Count); foreach (MethodNode method in classNode.Methods) WriteMethod(afterConstantPoolDataStream, method, state); if (classNode.Attributes.Count > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(classNode.Attributes.Count), $"Too many attributes: {classNode.Attributes.Count} > {ushort.MaxValue}"); - Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort)classNode.Attributes.Count); + Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort) classNode.Attributes.Count); foreach (AttributeNode attriute in classNode.Attributes) WriteAttribute(afterConstantPoolDataStream, attriute, state, AttributeScope.Class); @@ -187,4 +173,4 @@ public static void WriteClass(Stream stream, ClassNode classNode) stream.Write(data, 0, data.Length); } } -} +} \ No newline at end of file diff --git a/JavaAsm/IO/ClassReaderState.cs b/JavaAsm/IO/ClassReaderState.cs index 0139ebb..f4d7d8e 100644 --- a/JavaAsm/IO/ClassReaderState.cs +++ b/JavaAsm/IO/ClassReaderState.cs @@ -1,7 +1,5 @@ -namespace JavaAsm.IO -{ - internal class ClassReaderState - { +namespace JavaAsm.IO { + internal class ClassReaderState { public ClassNode ClassNode { get; set; } public ConstantPool ConstantPool { get; set; } diff --git a/JavaAsm/IO/ClassWriterState.cs b/JavaAsm/IO/ClassWriterState.cs index d8c67fb..185016d 100644 --- a/JavaAsm/IO/ClassWriterState.cs +++ b/JavaAsm/IO/ClassWriterState.cs @@ -1,7 +1,5 @@ -namespace JavaAsm.IO -{ - internal class ClassWriterState - { +namespace JavaAsm.IO { + internal class ClassWriterState { public ClassNode ClassNode { get; set; } public ConstantPool ConstantPool { get; set; } diff --git a/JavaAsm/IO/ConstantPool.cs b/JavaAsm/IO/ConstantPool.cs index 654ec40..e14805f 100644 --- a/JavaAsm/IO/ConstantPool.cs +++ b/JavaAsm/IO/ConstantPool.cs @@ -38,20 +38,48 @@ public void Read(Stream stream) { EntryTag tag = (EntryTag) stream.ReadByteFully(); Entry entry; switch (tag) { - case EntryTag.Class: entry = new ClassEntry(stream); break; - case EntryTag.FieldReference: entry = new FieldReferenceEntry(stream); break; - case EntryTag.MethodReference: entry = new MethodReferenceEntry(stream); break; - case EntryTag.InterfaceMethodReference: entry = new InterfaceMethodReferenceEntry(stream); break; - case EntryTag.String: entry = new StringEntry(stream); break; - case EntryTag.Integer: entry = new IntegerEntry(stream); break; - case EntryTag.Float: entry = new FloatEntry(stream); break; - case EntryTag.Long: entry = new LongEntry(stream); break; - case EntryTag.Double: entry = new DoubleEntry(stream); break; - case EntryTag.NameAndType: entry = new NameAndTypeEntry(stream); break; - case EntryTag.Utf8: entry = new Utf8Entry(stream); break; - case EntryTag.MethodHandle: entry = new MethodHandleEntry(stream); break; - case EntryTag.MethodType: entry = new MethodTypeEntry(stream); break; - case EntryTag.InvokeDynamic: entry = new InvokeDynamicEntry(stream); break; + case EntryTag.Class: + entry = new ClassEntry(stream); + break; + case EntryTag.FieldReference: + entry = new FieldReferenceEntry(stream); + break; + case EntryTag.MethodReference: + entry = new MethodReferenceEntry(stream); + break; + case EntryTag.InterfaceMethodReference: + entry = new InterfaceMethodReferenceEntry(stream); + break; + case EntryTag.String: + entry = new StringEntry(stream); + break; + case EntryTag.Integer: + entry = new IntegerEntry(stream); + break; + case EntryTag.Float: + entry = new FloatEntry(stream); + break; + case EntryTag.Long: + entry = new LongEntry(stream); + break; + case EntryTag.Double: + entry = new DoubleEntry(stream); + break; + case EntryTag.NameAndType: + entry = new NameAndTypeEntry(stream); + break; + case EntryTag.Utf8: + entry = new Utf8Entry(stream); + break; + case EntryTag.MethodHandle: + entry = new MethodHandleEntry(stream); + break; + case EntryTag.MethodType: + entry = new MethodTypeEntry(stream); + break; + case EntryTag.InvokeDynamic: + entry = new InvokeDynamicEntry(stream); + break; default: throw new ArgumentOutOfRangeException(nameof(tag)); } diff --git a/JavaAsm/IO/ConstantPoolEntries/ClassEntry.cs b/JavaAsm/IO/ConstantPoolEntries/ClassEntry.cs index ade76bb..e725215 100644 --- a/JavaAsm/IO/ConstantPoolEntries/ClassEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/ClassEntry.cs @@ -3,55 +3,47 @@ using System.IO; using BinaryEncoding; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class ClassEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class ClassEntry : Entry { public Utf8Entry Name { get; private set; } private ushort nameIndex; - public ClassEntry(Utf8Entry name) - { + public ClassEntry(Utf8Entry name) { this.Name = name ?? throw new ArgumentNullException(nameof(name)); } - public ClassEntry(Stream stream) - { + public ClassEntry(Stream stream) { this.nameIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.Class; - public override void ProcessFromConstantPool(ConstantPool constantPool) - { + public override void ProcessFromConstantPool(ConstantPool constantPool) { this.Name = constantPool.GetEntry(this.nameIndex); } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { Binary.BigEndian.Write(stream, this.nameIndex); } - public override void PutToConstantPool(ConstantPool constantPool) - { + public override void PutToConstantPool(ConstantPool constantPool) { this.nameIndex = constantPool.Find(this.Name); } - private bool Equals(ClassEntry other) - { + private bool Equals(ClassEntry other) { return this.Name.Equals(other.Name); } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((ClassEntry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((ClassEntry) obj); } [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] - public override int GetHashCode() - { + public override int GetHashCode() { return this.Name.GetHashCode(); } } diff --git a/JavaAsm/IO/ConstantPoolEntries/DoubleEntry.cs b/JavaAsm/IO/ConstantPoolEntries/DoubleEntry.cs index afc3e63..e0d2384 100644 --- a/JavaAsm/IO/ConstantPoolEntries/DoubleEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/DoubleEntry.cs @@ -2,19 +2,15 @@ using System.IO; using BinaryEncoding; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class DoubleEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class DoubleEntry : Entry { public double Value { get; } - public DoubleEntry(double value) - { + public DoubleEntry(double value) { this.Value = value; } - public DoubleEntry(Stream stream) - { + public DoubleEntry(Stream stream) { this.Value = BitConverter.Int64BitsToDouble(Binary.BigEndian.ReadInt64(stream)); } @@ -22,27 +18,25 @@ public DoubleEntry(Stream stream) public override void ProcessFromConstantPool(ConstantPool constantPool) { } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { Binary.BigEndian.Write(stream, BitConverter.DoubleToInt64Bits(this.Value)); } public override void PutToConstantPool(ConstantPool constantPool) { } - private bool Equals(DoubleEntry other) - { + private bool Equals(DoubleEntry other) { return this.Value.Equals(other.Value); } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((DoubleEntry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((DoubleEntry) obj); } - public override int GetHashCode() - { + public override int GetHashCode() { return this.Value.GetHashCode(); } } diff --git a/JavaAsm/IO/ConstantPoolEntries/Entry.cs b/JavaAsm/IO/ConstantPoolEntries/Entry.cs index 1bca067..b5e65b5 100644 --- a/JavaAsm/IO/ConstantPoolEntries/Entry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/Entry.cs @@ -1,9 +1,7 @@ using System.IO; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal abstract class Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal abstract class Entry { public abstract EntryTag Tag { get; } public abstract void ProcessFromConstantPool(ConstantPool constantPool); @@ -12,4 +10,4 @@ internal abstract class Entry public abstract void PutToConstantPool(ConstantPool constantPool); } -} +} \ No newline at end of file diff --git a/JavaAsm/IO/ConstantPoolEntries/EntryTag.cs b/JavaAsm/IO/ConstantPoolEntries/EntryTag.cs index 11a4862..d47b641 100644 --- a/JavaAsm/IO/ConstantPoolEntries/EntryTag.cs +++ b/JavaAsm/IO/ConstantPoolEntries/EntryTag.cs @@ -1,7 +1,5 @@ -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal enum EntryTag : byte - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal enum EntryTag : byte { Class = 7, FieldReference = 9, MethodReference = 10, diff --git a/JavaAsm/IO/ConstantPoolEntries/FieldReferenceEntry.cs b/JavaAsm/IO/ConstantPoolEntries/FieldReferenceEntry.cs index 789b859..722518d 100644 --- a/JavaAsm/IO/ConstantPoolEntries/FieldReferenceEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/FieldReferenceEntry.cs @@ -1,9 +1,7 @@ using System.IO; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class FieldReferenceEntry : ReferenceEntry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class FieldReferenceEntry : ReferenceEntry { public FieldReferenceEntry(ClassEntry @class, NameAndTypeEntry nameAndType) : base(@class, nameAndType) { } public override EntryTag Tag => EntryTag.FieldReference; diff --git a/JavaAsm/IO/ConstantPoolEntries/IntegerEntry.cs b/JavaAsm/IO/ConstantPoolEntries/IntegerEntry.cs index 5756010..b47ac40 100644 --- a/JavaAsm/IO/ConstantPoolEntries/IntegerEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/IntegerEntry.cs @@ -1,19 +1,15 @@ using System.IO; using BinaryEncoding; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class IntegerEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class IntegerEntry : Entry { public int Value { get; } - public IntegerEntry(int value) - { + public IntegerEntry(int value) { this.Value = value; } - public IntegerEntry(Stream stream) - { + public IntegerEntry(Stream stream) { this.Value = Binary.BigEndian.ReadInt32(stream); } @@ -21,27 +17,25 @@ public IntegerEntry(Stream stream) public override void ProcessFromConstantPool(ConstantPool constantPool) { } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { Binary.BigEndian.Write(stream, this.Value); } public override void PutToConstantPool(ConstantPool constantPool) { } - private bool Equals(IntegerEntry other) - { + private bool Equals(IntegerEntry other) { return this.Value == other.Value; } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((IntegerEntry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((IntegerEntry) obj); } - public override int GetHashCode() - { + public override int GetHashCode() { return this.Value; } } diff --git a/JavaAsm/IO/ConstantPoolEntries/InterfaceMethodReferenceEntry.cs b/JavaAsm/IO/ConstantPoolEntries/InterfaceMethodReferenceEntry.cs index d9c89de..f7f6194 100644 --- a/JavaAsm/IO/ConstantPoolEntries/InterfaceMethodReferenceEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/InterfaceMethodReferenceEntry.cs @@ -1,9 +1,7 @@ using System.IO; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class InterfaceMethodReferenceEntry : MethodReferenceEntry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class InterfaceMethodReferenceEntry : MethodReferenceEntry { public InterfaceMethodReferenceEntry(ClassEntry @class, NameAndTypeEntry nameAndType) : base(@class, nameAndType) { } public override EntryTag Tag => EntryTag.InterfaceMethodReference; diff --git a/JavaAsm/IO/ConstantPoolEntries/InvokeDynamicEntry.cs b/JavaAsm/IO/ConstantPoolEntries/InvokeDynamicEntry.cs index 84c6976..34afbc7 100644 --- a/JavaAsm/IO/ConstantPoolEntries/InvokeDynamicEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/InvokeDynamicEntry.cs @@ -3,62 +3,53 @@ using System.IO; using BinaryEncoding; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class InvokeDynamicEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class InvokeDynamicEntry : Entry { public ushort BootstrapMethodAttributeIndex { get; } public NameAndTypeEntry NameAndType { get; private set; } private ushort nameAndTypeIndex; - public InvokeDynamicEntry(ushort bootstrapMethodAttributeIndex, NameAndTypeEntry nameAndType) - { + public InvokeDynamicEntry(ushort bootstrapMethodAttributeIndex, NameAndTypeEntry nameAndType) { this.BootstrapMethodAttributeIndex = bootstrapMethodAttributeIndex; this.NameAndType = nameAndType ?? throw new ArgumentNullException(nameof(nameAndType)); } - public InvokeDynamicEntry(Stream stream) - { + public InvokeDynamicEntry(Stream stream) { this.BootstrapMethodAttributeIndex = Binary.BigEndian.ReadUInt16(stream); this.nameAndTypeIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.InvokeDynamic; - public override void ProcessFromConstantPool(ConstantPool constantPool) - { + public override void ProcessFromConstantPool(ConstantPool constantPool) { this.NameAndType = constantPool.GetEntry(this.nameAndTypeIndex); } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { Binary.BigEndian.Write(stream, this.BootstrapMethodAttributeIndex); Binary.BigEndian.Write(stream, this.nameAndTypeIndex); } - public override void PutToConstantPool(ConstantPool constantPool) - { + public override void PutToConstantPool(ConstantPool constantPool) { this.nameAndTypeIndex = constantPool.Find(this.NameAndType); } - private bool Equals(InvokeDynamicEntry other) - { + private bool Equals(InvokeDynamicEntry other) { return this.BootstrapMethodAttributeIndex == other.BootstrapMethodAttributeIndex && Equals(this.NameAndType, other.NameAndType); } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((InvokeDynamicEntry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((InvokeDynamicEntry) obj); } [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] - public override int GetHashCode() - { - unchecked - { + public override int GetHashCode() { + unchecked { return (this.BootstrapMethodAttributeIndex.GetHashCode() * 397) ^ (this.NameAndType != null ? this.NameAndType.GetHashCode() : 0); } } diff --git a/JavaAsm/IO/ConstantPoolEntries/LongEntry.cs b/JavaAsm/IO/ConstantPoolEntries/LongEntry.cs index 2c9dd51..5dca14f 100644 --- a/JavaAsm/IO/ConstantPoolEntries/LongEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/LongEntry.cs @@ -1,19 +1,15 @@ using System.IO; using BinaryEncoding; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class LongEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class LongEntry : Entry { public long Value { get; } - public LongEntry(long value) - { + public LongEntry(long value) { this.Value = value; } - public LongEntry(Stream stream) - { + public LongEntry(Stream stream) { this.Value = Binary.BigEndian.ReadInt64(stream); } @@ -21,27 +17,25 @@ public LongEntry(Stream stream) public override void ProcessFromConstantPool(ConstantPool constantPool) { } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { Binary.BigEndian.Write(stream, this.Value); } public override void PutToConstantPool(ConstantPool constantPool) { } - private bool Equals(LongEntry other) - { + private bool Equals(LongEntry other) { return this.Value == other.Value; } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((LongEntry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((LongEntry) obj); } - public override int GetHashCode() - { + public override int GetHashCode() { return this.Value.GetHashCode(); } } diff --git a/JavaAsm/IO/ConstantPoolEntries/MethodHandleEntry.cs b/JavaAsm/IO/ConstantPoolEntries/MethodHandleEntry.cs index deaa0d4..f138850 100644 --- a/JavaAsm/IO/ConstantPoolEntries/MethodHandleEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/MethodHandleEntry.cs @@ -5,33 +5,27 @@ using JavaAsm.Helpers; using JavaAsm.Instructions.Types; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class MethodHandleEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class MethodHandleEntry : Entry { public ReferenceKindType ReferenceKind { get; } public ReferenceEntry Reference { get; private set; } private ushort referenceIndex; - public MethodHandleEntry(ReferenceKindType referenceKind, ReferenceEntry reference) - { + public MethodHandleEntry(ReferenceKindType referenceKind, ReferenceEntry reference) { this.ReferenceKind = referenceKind; this.Reference = reference ?? throw new ArgumentNullException(nameof(reference)); } - public MethodHandleEntry(Stream stream) - { + public MethodHandleEntry(Stream stream) { this.ReferenceKind = (ReferenceKindType) stream.ReadByteFully(); this.referenceIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.MethodHandle; - public override void ProcessFromConstantPool(ConstantPool constantPool) - { - switch (this.ReferenceKind) - { + public override void ProcessFromConstantPool(ConstantPool constantPool) { + switch (this.ReferenceKind) { case ReferenceKindType.GetField: case ReferenceKindType.GetStatic: case ReferenceKindType.PutField: @@ -44,51 +38,45 @@ public override void ProcessFromConstantPool(ConstantPool constantPool) break; case ReferenceKindType.InvokeStatic: case ReferenceKindType.InvokeSpecial: - try - { + try { this.Reference = constantPool.GetEntry(this.referenceIndex); } - catch (InvalidCastException) - { + catch (InvalidCastException) { this.Reference = constantPool.GetEntry(this.referenceIndex); } + break; case ReferenceKindType.InvokeReference: this.Reference = constantPool.GetEntry(this.referenceIndex); break; - default: - throw new ArgumentOutOfRangeException(nameof(this.ReferenceKind)); + default: throw new ArgumentOutOfRangeException(nameof(this.ReferenceKind)); } } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { stream.WriteByte((byte) this.ReferenceKind); Binary.BigEndian.Write(stream, this.referenceIndex); } - public override void PutToConstantPool(ConstantPool constantPool) - { + public override void PutToConstantPool(ConstantPool constantPool) { this.referenceIndex = constantPool.Find(this.Reference); } - private bool Equals(MethodHandleEntry other) - { + private bool Equals(MethodHandleEntry other) { return this.ReferenceKind == other.ReferenceKind && Equals(this.Reference, other.Reference); } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((MethodHandleEntry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((MethodHandleEntry) obj); } [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] - public override int GetHashCode() - { - unchecked - { + public override int GetHashCode() { + unchecked { return ((int) this.ReferenceKind * 397) ^ (this.Reference != null ? this.Reference.GetHashCode() : 0); } } diff --git a/JavaAsm/IO/ConstantPoolEntries/MethodReferenceEntry.cs b/JavaAsm/IO/ConstantPoolEntries/MethodReferenceEntry.cs index 717c008..f17c13f 100644 --- a/JavaAsm/IO/ConstantPoolEntries/MethodReferenceEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/MethodReferenceEntry.cs @@ -1,9 +1,7 @@ using System.IO; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class MethodReferenceEntry : ReferenceEntry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class MethodReferenceEntry : ReferenceEntry { public MethodReferenceEntry(ClassEntry @class, NameAndTypeEntry nameAndType) : base(@class, nameAndType) { } public override EntryTag Tag => EntryTag.MethodReference; diff --git a/JavaAsm/IO/ConstantPoolEntries/MethodTypeEntry.cs b/JavaAsm/IO/ConstantPoolEntries/MethodTypeEntry.cs index 63caaf0..808dd8c 100644 --- a/JavaAsm/IO/ConstantPoolEntries/MethodTypeEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/MethodTypeEntry.cs @@ -3,55 +3,47 @@ using System.IO; using BinaryEncoding; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class MethodTypeEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class MethodTypeEntry : Entry { public Utf8Entry Descriptor { get; private set; } private ushort descriptorIndex; - public MethodTypeEntry(Utf8Entry descriptor) - { + public MethodTypeEntry(Utf8Entry descriptor) { this.Descriptor = descriptor ?? throw new ArgumentNullException(nameof(descriptor)); } - public MethodTypeEntry(Stream stream) - { + public MethodTypeEntry(Stream stream) { this.descriptorIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.MethodType; - public override void ProcessFromConstantPool(ConstantPool constantPool) - { + public override void ProcessFromConstantPool(ConstantPool constantPool) { this.Descriptor = constantPool.GetEntry(this.descriptorIndex); } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { Binary.BigEndian.Write(stream, this.descriptorIndex); } - public override void PutToConstantPool(ConstantPool constantPool) - { + public override void PutToConstantPool(ConstantPool constantPool) { this.descriptorIndex = constantPool.Find(this.Descriptor); } - private bool Equals(MethodTypeEntry other) - { + private bool Equals(MethodTypeEntry other) { return Equals(this.Descriptor, other.Descriptor); } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((MethodTypeEntry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((MethodTypeEntry) obj); } [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] - public override int GetHashCode() - { + public override int GetHashCode() { return this.Descriptor != null ? this.Descriptor.GetHashCode() : 0; } } diff --git a/JavaAsm/IO/ConstantPoolEntries/NameAndTypeEntry.cs b/JavaAsm/IO/ConstantPoolEntries/NameAndTypeEntry.cs index df1cf20..9482d48 100644 --- a/JavaAsm/IO/ConstantPoolEntries/NameAndTypeEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/NameAndTypeEntry.cs @@ -3,65 +3,56 @@ using System.IO; using BinaryEncoding; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class NameAndTypeEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class NameAndTypeEntry : Entry { public Utf8Entry Name { get; private set; } private ushort nameIndex; public Utf8Entry Descriptor { get; private set; } private ushort descriptorIndex; - public NameAndTypeEntry(Utf8Entry name, Utf8Entry descriptor) - { + public NameAndTypeEntry(Utf8Entry name, Utf8Entry descriptor) { this.Name = name ?? throw new ArgumentNullException(nameof(name)); this.Descriptor = descriptor ?? throw new ArgumentNullException(nameof(descriptor)); } - public NameAndTypeEntry(Stream stream) - { + public NameAndTypeEntry(Stream stream) { this.nameIndex = Binary.BigEndian.ReadUInt16(stream); this.descriptorIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.NameAndType; - public override void ProcessFromConstantPool(ConstantPool constantPool) - { + public override void ProcessFromConstantPool(ConstantPool constantPool) { this.Name = constantPool.GetEntry(this.nameIndex); this.Descriptor = constantPool.GetEntry(this.descriptorIndex); } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { Binary.BigEndian.Write(stream, this.nameIndex); Binary.BigEndian.Write(stream, this.descriptorIndex); } - public override void PutToConstantPool(ConstantPool constantPool) - { + public override void PutToConstantPool(ConstantPool constantPool) { this.nameIndex = constantPool.Find(this.Name); this.descriptorIndex = constantPool.Find(this.Descriptor); } - private bool Equals(NameAndTypeEntry other) - { + private bool Equals(NameAndTypeEntry other) { return this.Name.Equals(other.Name) && this.Descriptor.Equals(other.Descriptor); } - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((NameAndTypeEntry)obj); + public override bool Equals(object obj) { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((NameAndTypeEntry) obj); } [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] - public override int GetHashCode() - { - unchecked - { + public override int GetHashCode() { + unchecked { return (this.Name.GetHashCode() * 397) ^ this.Descriptor.GetHashCode(); } } diff --git a/JavaAsm/IO/ConstantPoolEntries/ReferenceEntry.cs b/JavaAsm/IO/ConstantPoolEntries/ReferenceEntry.cs index 2ea7cd8..cfafa0c 100644 --- a/JavaAsm/IO/ConstantPoolEntries/ReferenceEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/ReferenceEntry.cs @@ -3,63 +3,54 @@ using System.IO; using BinaryEncoding; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal abstract class ReferenceEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal abstract class ReferenceEntry : Entry { public ClassEntry Class { get; private set; } private ushort classIndex; public NameAndTypeEntry NameAndType { get; private set; } private ushort nameAndTypeIndex; - protected ReferenceEntry(ClassEntry @class, NameAndTypeEntry nameAndType) - { + protected ReferenceEntry(ClassEntry @class, NameAndTypeEntry nameAndType) { this.Class = @class ?? throw new ArgumentNullException(nameof(@class)); this.NameAndType = nameAndType ?? throw new ArgumentNullException(nameof(nameAndType)); } - protected ReferenceEntry(Stream stream) - { + protected ReferenceEntry(Stream stream) { this.classIndex = Binary.BigEndian.ReadUInt16(stream); this.nameAndTypeIndex = Binary.BigEndian.ReadUInt16(stream); } - public override void ProcessFromConstantPool(ConstantPool constantPool) - { + public override void ProcessFromConstantPool(ConstantPool constantPool) { this.Class = constantPool.GetEntry(this.classIndex); this.NameAndType = constantPool.GetEntry(this.nameAndTypeIndex); } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { Binary.BigEndian.Write(stream, this.classIndex); Binary.BigEndian.Write(stream, this.nameAndTypeIndex); } - public override void PutToConstantPool(ConstantPool constantPool) - { + public override void PutToConstantPool(ConstantPool constantPool) { this.classIndex = constantPool.Find(this.Class); this.nameAndTypeIndex = constantPool.Find(this.NameAndType); } - private bool Equals(ReferenceEntry other) - { + private bool Equals(ReferenceEntry other) { return this.Class.Equals(other.Class) && this.NameAndType.Equals(other.NameAndType); } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((ReferenceEntry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((ReferenceEntry) obj); } [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] - public override int GetHashCode() - { - unchecked - { + public override int GetHashCode() { + unchecked { return (this.Class.GetHashCode() * 397) ^ this.NameAndType.GetHashCode(); } } diff --git a/JavaAsm/IO/ConstantPoolEntries/StringEntry.cs b/JavaAsm/IO/ConstantPoolEntries/StringEntry.cs index 27512d2..638d4c8 100644 --- a/JavaAsm/IO/ConstantPoolEntries/StringEntry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/StringEntry.cs @@ -3,55 +3,47 @@ using System.IO; using BinaryEncoding; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class StringEntry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class StringEntry : Entry { public Utf8Entry Value { get; private set; } private ushort nameIndex; - public StringEntry(Utf8Entry @string) - { + public StringEntry(Utf8Entry @string) { this.Value = @string ?? throw new ArgumentNullException(nameof(@string)); } - public StringEntry(Stream stream) - { + public StringEntry(Stream stream) { this.nameIndex = Binary.BigEndian.ReadUInt16(stream); } public override EntryTag Tag => EntryTag.String; - public override void ProcessFromConstantPool(ConstantPool constantPool) - { + public override void ProcessFromConstantPool(ConstantPool constantPool) { this.Value = constantPool.GetEntry(this.nameIndex); } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { Binary.BigEndian.Write(stream, this.nameIndex); } - public override void PutToConstantPool(ConstantPool constantPool) - { + public override void PutToConstantPool(ConstantPool constantPool) { this.nameIndex = constantPool.Find(this.Value); } - private bool Equals(StringEntry other) - { + private bool Equals(StringEntry other) { return this.Value.Equals(other.Value); } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((StringEntry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((StringEntry) obj); } [SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")] - public override int GetHashCode() - { + public override int GetHashCode() { return this.Value.GetHashCode(); } } diff --git a/JavaAsm/IO/ConstantPoolEntries/Utf8Entry.cs b/JavaAsm/IO/ConstantPoolEntries/Utf8Entry.cs index 653e2ae..f0aaa04 100644 --- a/JavaAsm/IO/ConstantPoolEntries/Utf8Entry.cs +++ b/JavaAsm/IO/ConstantPoolEntries/Utf8Entry.cs @@ -3,19 +3,15 @@ using BinaryEncoding; using JavaAsm.Helpers; -namespace JavaAsm.IO.ConstantPoolEntries -{ - internal class Utf8Entry : Entry - { +namespace JavaAsm.IO.ConstantPoolEntries { + internal class Utf8Entry : Entry { public string String { get; } - public Utf8Entry(string @string) - { + public Utf8Entry(string @string) { this.String = @string ?? throw new ArgumentNullException(nameof(@string)); } - public Utf8Entry(Stream stream) - { + public Utf8Entry(Stream stream) { byte[] data = new byte[Binary.BigEndian.ReadUInt16(stream)]; stream.Read(data, 0, data.Length); this.String = ModifiedUtf8Helper.Decode(data); @@ -25,28 +21,26 @@ public Utf8Entry(Stream stream) public override void ProcessFromConstantPool(ConstantPool constantPool) { } - public override void Write(Stream stream) - { + public override void Write(Stream stream) { Binary.BigEndian.Write(stream, ModifiedUtf8Helper.GetBytesCount(this.String)); stream.Write(ModifiedUtf8Helper.Encode(this.String)); } public override void PutToConstantPool(ConstantPool constantPool) { } - private bool Equals(Utf8Entry other) - { + private bool Equals(Utf8Entry other) { return this.String == other.String; } - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((Utf8Entry)obj); + public override bool Equals(object obj) { + if (obj is null) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj.GetType() == GetType() && Equals((Utf8Entry) obj); } - public override int GetHashCode() - { + public override int GetHashCode() { return this.String.GetHashCode(); } } diff --git a/JavaAsm/Instructions/Instruction.cs b/JavaAsm/Instructions/Instruction.cs index 8b283fb..ede3e52 100644 --- a/JavaAsm/Instructions/Instruction.cs +++ b/JavaAsm/Instructions/Instruction.cs @@ -1,7 +1,5 @@ -namespace JavaAsm.Instructions -{ - public abstract class Instruction - { +namespace JavaAsm.Instructions { + public abstract class Instruction { public InstructionList OwnerList { get; internal set; } public Instruction Previous { get; internal set; } @@ -10,4 +8,4 @@ public abstract class Instruction public abstract Opcode Opcode { get; set; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/InstructionList.cs b/JavaAsm/Instructions/InstructionList.cs index 255d20a..14e36a5 100644 --- a/JavaAsm/Instructions/InstructionList.cs +++ b/JavaAsm/Instructions/InstructionList.cs @@ -2,32 +2,26 @@ using System.Collections; using System.Collections.Generic; -namespace JavaAsm.Instructions -{ - public class InstructionList : IEnumerable - { - private class InstructionListEnumerator : IEnumerator - { - public InstructionListEnumerator(Instruction start) - { +namespace JavaAsm.Instructions { + public class InstructionList : IEnumerable { + private class InstructionListEnumerator : IEnumerator { + public InstructionListEnumerator(Instruction start) { this.Start = start; } - public bool MoveNext() - { - if (this.Start != null && this.Current == null) - { + public bool MoveNext() { + if (this.Start != null && this.Current == null) { this.Current = this.Start; return true; } + if (this.Current?.Next == null) return false; this.Current = this.Current.Next; return true; } - public void Reset() - { + public void Reset() { this.Current = null; } @@ -46,8 +40,7 @@ public void Dispose() { } public int Count { get; private set; } - public void Add(Instruction instruction) - { + public void Add(Instruction instruction) { instruction.OwnerList = this; instruction.Next = null; if (this.First == null) @@ -59,8 +52,7 @@ public void Add(Instruction instruction) this.Count++; } - public void InsertBefore(Instruction instruction, Instruction toInsert) - { + public void InsertBefore(Instruction instruction, Instruction toInsert) { if (instruction.OwnerList != this) throw new ArgumentException("Position instruction does not belong to that list", nameof(instruction.OwnerList)); toInsert.OwnerList = this; @@ -76,8 +68,7 @@ public void InsertBefore(Instruction instruction, Instruction toInsert) this.Count++; } - public void InsertAfter(Instruction instruction, Instruction toInsert) - { + public void InsertAfter(Instruction instruction, Instruction toInsert) { if (instruction.OwnerList != this) throw new ArgumentException("Position instruction does not belong to that list", nameof(instruction.OwnerList)); toInsert.OwnerList = this; @@ -93,8 +84,7 @@ public void InsertAfter(Instruction instruction, Instruction toInsert) this.Count++; } - public void Remove(Instruction instruction) - { + public void Remove(Instruction instruction) { if (instruction.OwnerList != this) throw new ArgumentException("Instruction does not belong to that list", nameof(instruction.OwnerList)); instruction.OwnerList = null; @@ -109,14 +99,12 @@ public void Remove(Instruction instruction) this.Count--; } - public IEnumerator GetEnumerator() - { + public IEnumerator GetEnumerator() { return new InstructionListEnumerator(this.First); } - IEnumerator IEnumerable.GetEnumerator() - { + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/InstructionListConverter.cs b/JavaAsm/Instructions/InstructionListConverter.cs index 709f8fd..3065784 100644 --- a/JavaAsm/Instructions/InstructionListConverter.cs +++ b/JavaAsm/Instructions/InstructionListConverter.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using BinaryEncoding; using JavaAsm.CustomAttributes; using JavaAsm.Helpers; @@ -9,20 +10,16 @@ using JavaAsm.IO; using JavaAsm.IO.ConstantPoolEntries; -namespace JavaAsm.Instructions -{ - internal static class InstructionListConverter - { - private static AttributeNode GetAttribute(ICollection attributes, string name) - { +namespace JavaAsm.Instructions { + internal static class InstructionListConverter { + private static AttributeNode GetAttribute(ICollection attributes, string name) { AttributeNode attribute = attributes.FirstOrDefault(a => a.Name == name); if (attribute != null) attributes.Remove(attribute); return attribute; } - public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState readerState, CodeAttribute codeAttribute) - { + public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState readerState, CodeAttribute codeAttribute) { parseTo.MaxStack = codeAttribute.MaxStack; parseTo.MaxLocals = codeAttribute.MaxLocals; parseTo.CodeAttributes = codeAttribute.Attributes; @@ -30,8 +27,7 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade if (codeAttribute.Code.Length == 0) return; - BootstrapMethodsAttribute bootstrapMethodsAttribute = readerState.ClassNode.Attributes - .FirstOrDefault(x => x.Name == PredefinedAttributeNames.BootstrapMethods)?.ParsedAttribute as BootstrapMethodsAttribute; + BootstrapMethodsAttribute bootstrapMethodsAttribute = readerState.ClassNode.Attributes.FirstOrDefault(x => x.Name == PredefinedAttributeNames.BootstrapMethods)?.ParsedAttribute as BootstrapMethodsAttribute; Dictionary instructions = new Dictionary(); Dictionary labels = new Dictionary(); @@ -436,12 +432,24 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade object ldcVal; switch (constantPoolEntry) { - case IntegerEntry ie: ldcVal = ie.Value; break; - case FloatEntry fe: ldcVal = fe.Value; break; - case StringEntry se: ldcVal = se.Value.String; break; - case ClassEntry ce: ldcVal = new ClassName(ce.Name.String); break; - case MethodTypeEntry mte: ldcVal = MethodDescriptor.Parse(mte.Descriptor.String); break; - case MethodHandleEntry mhe: ldcVal = Handle.FromConstantPool(mhe); break; + case IntegerEntry ie: + ldcVal = ie.Value; + break; + case FloatEntry fe: + ldcVal = fe.Value; + break; + case StringEntry se: + ldcVal = se.Value.String; + break; + case ClassEntry ce: + ldcVal = new ClassName(ce.Name.String); + break; + case MethodTypeEntry mte: + ldcVal = MethodDescriptor.Parse(mte.Descriptor.String); + break; + case MethodHandleEntry mhe: + ldcVal = Handle.FromConstantPool(mhe); + break; default: throw new ArgumentOutOfRangeException(nameof(constantPoolEntry), $"Tried to {opcode} wrong type of CP entry: {constantPoolEntry.Tag}"); } @@ -453,14 +461,30 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade Entry constantPoolEntry = readerState.ConstantPool.GetEntry(Binary.BigEndian.ReadUInt16(codeStream)); object ldcValue; switch (constantPoolEntry) { - case IntegerEntry ie when opcode == Opcode.LDC_W: ldcValue = ie.Value; break; - case FloatEntry fe when opcode == Opcode.LDC_W: ldcValue = fe.Value; break; - case StringEntry se when opcode == Opcode.LDC_W: ldcValue = se.Value.String; break; - case ClassEntry ce when opcode == Opcode.LDC_W: ldcValue = new ClassName(ce.Name.String); break; - case MethodTypeEntry mte when opcode == Opcode.LDC_W: ldcValue = MethodDescriptor.Parse(mte.Descriptor.String); break; - case MethodHandleEntry mhe when opcode == Opcode.LDC_W: ldcValue = new Handle {Descriptor = mhe.ReferenceKind.IsFieldReference() ? TypeDescriptor.Parse(mhe.Reference.NameAndType.Descriptor.String) : (IDescriptor) MethodDescriptor.Parse(mhe.Reference.NameAndType.Descriptor.String), Name = mhe.Reference.NameAndType.Name.String, Owner = new ClassName(mhe.Reference.Class.Name.String)}; break; - case DoubleEntry de when opcode == Opcode.LDC2_W: ldcValue = de.Value; break; - case LongEntry le when opcode == Opcode.LDC2_W: ldcValue = le.Value; break; + case IntegerEntry ie when opcode == Opcode.LDC_W: + ldcValue = ie.Value; + break; + case FloatEntry fe when opcode == Opcode.LDC_W: + ldcValue = fe.Value; + break; + case StringEntry se when opcode == Opcode.LDC_W: + ldcValue = se.Value.String; + break; + case ClassEntry ce when opcode == Opcode.LDC_W: + ldcValue = new ClassName(ce.Name.String); + break; + case MethodTypeEntry mte when opcode == Opcode.LDC_W: + ldcValue = MethodDescriptor.Parse(mte.Descriptor.String); + break; + case MethodHandleEntry mhe when opcode == Opcode.LDC_W: + ldcValue = new Handle {Descriptor = mhe.ReferenceKind.IsFieldReference() ? TypeDescriptor.Parse(mhe.Reference.NameAndType.Descriptor.String) : (IDescriptor) MethodDescriptor.Parse(mhe.Reference.NameAndType.Descriptor.String), Name = mhe.Reference.NameAndType.Name.String, Owner = new ClassName(mhe.Reference.Class.Name.String)}; + break; + case DoubleEntry de when opcode == Opcode.LDC2_W: + ldcValue = de.Value; + break; + case LongEntry le when opcode == Opcode.LDC2_W: + ldcValue = le.Value; + break; default: throw new ArgumentOutOfRangeException(nameof(constantPoolEntry), $"Tried to {opcode} wrong type of CP entry: {constantPoolEntry.GetType()}"); } @@ -489,13 +513,10 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade throw new ArgumentException("Label key is not at the beginning of instruction"); parseTo.Instructions = new InstructionList(); - parseTo.TryCatches.Capacity = codeAttribute.ExceptionTable.Count; - foreach (CodeAttribute.ExceptionTableEntry exceptionTableEntry in codeAttribute.ExceptionTable) - { - parseTo.TryCatches.Add(new TryCatchNode - { + foreach (CodeAttribute.ExceptionTableEntry exceptionTableEntry in codeAttribute.ExceptionTable) { + parseTo.TryCatches.Add(new TryCatchNode { ExceptionClassName = exceptionTableEntry.CatchType, Start = labels.GetOrAdd(exceptionTableEntry.StartPc, new Label()), End = labels.GetOrAdd(exceptionTableEntry.EndPc, new Label()), @@ -504,59 +525,66 @@ public static void ParseCodeAttribute(MethodNode parseTo, ClassReaderState reade } List> instructionList = instructions.OrderBy(x => x.Key).ToList(); - List> labelList = labels.OrderBy(x => x.Key).ToList(); - int labelListPosition = 0; - - List lineNumberTable = ((GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.LineNumberTable)?.ParsedAttribute - as LineNumberTableAttribute)?.LineNumberTable ?? new List()).OrderBy(x => x.StartPc).ToList(); + List lineNumberTable = ((GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.LineNumberTable)?.ParsedAttribute as LineNumberTableAttribute)?.LineNumberTable ?? new List()).OrderBy(x => x.StartPc).ToList(); if (lineNumberTable.Any(position => !instructions.ContainsKey(position.StartPc))) throw new ArgumentException("Line number is not at the beginning of instruction"); - int lineNumberTablePosition = 0; + if (parseTo.LocalVariableNames == null) { + parseTo.LocalVariableNames = new Dictionary(); + } + else { + parseTo.LocalVariableNames.Clear(); + } + + if (GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.LocalVariableTable)?.ParsedAttribute is LocalVariableTableAttribute lvt && lvt.LocalVariableTable != null) { + List localVariableTable = lvt.LocalVariableTable.OrderBy(x => x.Index).ToList(); + foreach (LocalVariableTableAttribute.LocalVariableTableEntry entry in localVariableTable) { + parseTo.LocalVariableNames[entry.Index] = new LocalVariableTableAttribute.LocalVariableTableEntry() { + StartPc = entry.StartPc, + Length = entry.Length, + Name = entry.Name, + Descriptor = entry.Descriptor, + Index = entry.Index + }; + } + } + + int labelListPosition = 0; + int lineNumberTablePosition = 0; List<(int Position, StackMapFrame Frame)> stackMapFrames = new List<(int Position, StackMapFrame Frame)>(); int stackMapFramesPosition = 0; { - List stackMapTable = (GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.StackMapTable)?.ParsedAttribute - as StackMapTableAttribute)?.Entries; - if (stackMapTable != null) - { + List stackMapTable = (GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.StackMapTable)?.ParsedAttribute as StackMapTableAttribute)?.Entries; + if (stackMapTable != null) { stackMapFrames.Capacity = stackMapTable.Count; int position = 0; bool hasProcessedFirst = false; - foreach (StackMapTableAttribute.StackMapFrame entry in stackMapTable) - { - VerificationElement ConvertVerificationElement(StackMapTableAttribute.VerificationElement sourceVerificationElement) - { + foreach (StackMapTableAttribute.StackMapFrame entry in stackMapTable) { + VerificationElement ConvertVerificationElement(StackMapTableAttribute.VerificationElement sourceVerificationElement) { VerificationElement verificationElement; - switch (sourceVerificationElement) - { + switch (sourceVerificationElement) { case StackMapTableAttribute.SimpleVerificationElement simpleVerificationElement: - verificationElement = new SimpleVerificationElement((VerificationElementType)simpleVerificationElement.Type); + verificationElement = new SimpleVerificationElement((VerificationElementType) simpleVerificationElement.Type); break; case StackMapTableAttribute.ObjectVerificationElement objectVerificationElement: - verificationElement = new ObjectVerificationElement - { + verificationElement = new ObjectVerificationElement { ObjectClass = objectVerificationElement.ObjectClass }; break; - case StackMapTableAttribute.UninitializedVerificationElement uninitializedVerificationElement: - { + case StackMapTableAttribute.UninitializedVerificationElement uninitializedVerificationElement: { Instruction newInstruction = instructions[uninitializedVerificationElement.NewInstructionOffset]; if (newInstruction.Opcode != Opcode.NEW) throw new ArgumentException( $"New instruction required by verification element is not NEW: {newInstruction.Opcode}", nameof(newInstruction)); - verificationElement = new UninitializedVerificationElement - { + verificationElement = new UninitializedVerificationElement { NewInstruction = (TypeInstruction) newInstruction }; break; } - default: - throw new ArgumentOutOfRangeException(nameof(verificationElement)); - + default: throw new ArgumentOutOfRangeException(nameof(verificationElement)); } return verificationElement; @@ -564,8 +592,7 @@ VerificationElement ConvertVerificationElement(StackMapTableAttribute.Verificati position += entry.OffsetDelta + (hasProcessedFirst ? 1 : 0); - StackMapFrame stackMapFrame = new StackMapFrame - { + StackMapFrame stackMapFrame = new StackMapFrame { Type = (FrameType) entry.Type, ChopK = entry.ChopK }; @@ -588,12 +615,10 @@ VerificationElement ConvertVerificationElement(StackMapTableAttribute.Verificati GetAttribute(codeAttribute.Attributes, PredefinedAttributeNames.LocalVariableTypeTable); } - foreach (KeyValuePair pair in instructionList) - { + foreach (KeyValuePair pair in instructionList) { while (lineNumberTablePosition < lineNumberTable.Count && pair.Key >= lineNumberTable[lineNumberTablePosition].StartPc) - parseTo.Instructions.Add(new LineNumber - { + parseTo.Instructions.Add(new LineNumber { Line = lineNumberTable[lineNumberTablePosition++].LineNumber }); while (labelListPosition < labelList.Count && pair.Key >= labelList[labelListPosition].Key) @@ -602,25 +627,22 @@ VerificationElement ConvertVerificationElement(StackMapTableAttribute.Verificati parseTo.Instructions.Add(stackMapFrames[stackMapFramesPosition++].Frame); parseTo.Instructions.Add(pair.Value); } + while (labelListPosition < labelList.Count) parseTo.Instructions.Add(labelList[labelListPosition++].Value); while (stackMapFramesPosition < stackMapFrames.Count) parseTo.Instructions.Add(stackMapFrames[stackMapFramesPosition++].Frame); } - public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterState writerState) - { - CodeAttribute codeAttribute = new CodeAttribute - { + public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterState writerState) { + CodeAttribute codeAttribute = new CodeAttribute { Attributes = source.CodeAttributes, MaxLocals = source.MaxLocals, MaxStack = source.MaxStack }; - foreach (Instruction instruction in source.Instructions) - { - switch (instruction) - { + foreach (Instruction instruction in source.Instructions) { + switch (instruction) { case FieldInstruction fieldInstruction: writerState.ConstantPool.Find(new FieldReferenceEntry( new ClassEntry(new Utf8Entry(fieldInstruction.Owner.Name)), @@ -639,14 +661,30 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat case LdcInstruction ldcInstruction: Entry entry; switch (ldcInstruction.Value) { - case int integerValue: entry = new IntegerEntry(integerValue); break; - case float floatValue: entry = new FloatEntry(floatValue); break; - case string stringValue: entry = new StringEntry(new Utf8Entry(stringValue)); break; - case long longValue: entry = new LongEntry(longValue); break; - case double doubleValue: entry = new DoubleEntry(doubleValue); break; - case ClassName className: entry = new ClassEntry(new Utf8Entry(className.Name)); break; - case Handle handle: entry = handle.ToConstantPool(); break; - case MethodDescriptor methodDescriptor: entry = new MethodTypeEntry(new Utf8Entry(methodDescriptor.ToString())); break; + case int integerValue: + entry = new IntegerEntry(integerValue); + break; + case float floatValue: + entry = new FloatEntry(floatValue); + break; + case string stringValue: + entry = new StringEntry(new Utf8Entry(stringValue)); + break; + case long longValue: + entry = new LongEntry(longValue); + break; + case double doubleValue: + entry = new DoubleEntry(doubleValue); + break; + case ClassName className: + entry = new ClassEntry(new Utf8Entry(className.Name)); + break; + case Handle handle: + entry = handle.ToConstantPool(); + break; + case MethodDescriptor methodDescriptor: + entry = new MethodTypeEntry(new Utf8Entry(methodDescriptor.ToString())); + break; default: throw new ArgumentOutOfRangeException(nameof(ldcInstruction.Value), $"Can't encode value of type {ldcInstruction.Value.GetType()}"); } @@ -660,8 +698,7 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat writerState.ClassNode.Attributes.FirstOrDefault(x => x.Name == PredefinedAttributeNames.BootstrapMethods); if (bootstrapMethodAttributeNode == null) - writerState.ClassNode.Attributes.Add(bootstrapMethodAttributeNode = new AttributeNode - { + writerState.ClassNode.Attributes.Add(bootstrapMethodAttributeNode = new AttributeNode { Name = PredefinedAttributeNames.BootstrapMethods, ParsedAttribute = new BootstrapMethodsAttribute() }); @@ -686,25 +723,19 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat case VariableInstruction _: case StackMapFrame _: break; - default: - throw new ArgumentOutOfRangeException(nameof(instruction)); + default: throw new ArgumentOutOfRangeException(nameof(instruction)); } } List lineNumbers = new List(); - List stackMapFrames = new List(); - int previousStackMapFramePosition = -1; - Dictionary instructions = new Dictionary(); - int currentPosition = 0; - foreach (Instruction instruction in source.Instructions) - { + int previousStackMapFramePosition = -1; + foreach (Instruction instruction in source.Instructions) { instructions.Add(instruction, (ushort) currentPosition); currentPosition += instruction.Opcode == Opcode.None ? 0 : sizeof(byte); - switch (instruction) - { + switch (instruction) { case FieldInstruction _: currentPosition += sizeof(ushort); break; @@ -717,8 +748,8 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat case IncrementInstruction incrementInstruction: currentPosition += incrementInstruction.VariableIndex > byte.MaxValue || incrementInstruction.Value > sbyte.MaxValue || incrementInstruction.Value < sbyte.MinValue - ? sizeof(ushort) * 2 + sizeof(byte) - : sizeof(byte) * 2; + ? sizeof(ushort) * 2 + sizeof(byte) + : sizeof(byte) * 2; break; case IntegerPushInstruction integerPushInstruction: currentPosition += integerPushInstruction.Opcode == Opcode.SIPUSH @@ -731,8 +762,7 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat case LdcInstruction ldcInstruction: if (ldcInstruction.Value is long || ldcInstruction.Value is double) currentPosition += sizeof(ushort); - else - { + else { ushort constantPoolEntryIndex; switch (ldcInstruction.Value) { case int integerValue: @@ -758,10 +788,10 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat currentPosition += constantPoolEntryIndex > byte.MaxValue ? sizeof(ushort) : sizeof(byte); } + break; case LineNumber lineNumber: - lineNumbers.Add(new LineNumberTableAttribute.LineNumberTableEntry - { + lineNumbers.Add(new LineNumberTableAttribute.LineNumberTableEntry { LineNumber = lineNumber.Line, StartPc = (ushort) currentPosition }); @@ -780,8 +810,7 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat case NewArrayInstruction _: currentPosition += sizeof(byte); break; - case SimpleInstruction _: - break; + case SimpleInstruction _: break; case TableSwitchInstruction tableSwitchInstruction: while (currentPosition % 4 != 0) currentPosition++; @@ -797,32 +826,27 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat case InvokeDynamicInstruction _: currentPosition += sizeof(ushort) + sizeof(ushort); break; - default: - throw new ArgumentOutOfRangeException(nameof(instruction)); + default: throw new ArgumentOutOfRangeException(nameof(instruction)); } if (currentPosition > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(currentPosition)); } - if (lineNumbers.Count > 0) - { + if (lineNumbers.Count > 0) { if (codeAttribute.Attributes.Any(x => x.Name == PredefinedAttributeNames.LineNumberTable)) throw new ArgumentException($"There is already a {PredefinedAttributeNames.LineNumberTable} attribute"); codeAttribute.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.LineNumberTable, - ParsedAttribute = new LineNumberTableAttribute - { + ParsedAttribute = new LineNumberTableAttribute { LineNumberTable = lineNumbers } }); } codeAttribute.ExceptionTable.Capacity = source.TryCatches.Count; - foreach (TryCatchNode tryCatchNode in source.TryCatches) - { - codeAttribute.ExceptionTable.Add(new CodeAttribute.ExceptionTableEntry - { + foreach (TryCatchNode tryCatchNode in source.TryCatches) { + codeAttribute.ExceptionTable.Add(new CodeAttribute.ExceptionTableEntry { CatchType = tryCatchNode.ExceptionClassName, StartPc = instructions[tryCatchNode.Start], EndPc = instructions[tryCatchNode.End], @@ -830,16 +854,25 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat }); } + if (source.LocalVariableNames != null && source.LocalVariableNames.Count > 0) { + if (codeAttribute.Attributes.Any(x => x.Name == PredefinedAttributeNames.LocalVariableTable)) + throw new ArgumentException($"There is already a {PredefinedAttributeNames.LocalVariableTable} attribute"); + codeAttribute.Attributes.Add(new AttributeNode { + Name = PredefinedAttributeNames.LocalVariableTable, + ParsedAttribute = new LocalVariableTableAttribute() { + LocalVariableTable = source.LocalVariableNames.ToList().Select(e => e.Value).ToList() + } + }); + } + MemoryStream codeDataStream = new MemoryStream(currentPosition); - foreach (Instruction instruction in source.Instructions) - { + foreach (Instruction instruction in source.Instructions) { ushort position = (ushort) codeDataStream.Position; if (position != instructions[instruction]) throw new Exception($"Wrong position: {position} != {instructions[instruction]}"); - switch (instruction) - { + switch (instruction) { case FieldInstruction fieldInstruction: codeDataStream.WriteByte((byte) fieldInstruction.Opcode); Binary.BigEndian.Write(codeDataStream, writerState.ConstantPool.Find(new FieldReferenceEntry( @@ -849,8 +882,7 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat break; case MethodInstruction methodInstruction: codeDataStream.WriteByte((byte) methodInstruction.Opcode); - if (methodInstruction.Opcode == Opcode.INVOKEINTERFACE) - { + if (methodInstruction.Opcode == Opcode.INVOKEINTERFACE) { Binary.BigEndian.Write(codeDataStream, writerState.ConstantPool.Find(new InterfaceMethodReferenceEntry( new ClassEntry(new Utf8Entry(methodInstruction.Owner.Name)), new NameAndTypeEntry(new Utf8Entry(methodInstruction.Name), @@ -861,13 +893,13 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat codeDataStream.WriteByte((byte) (methodInstruction.Descriptor.ArgumentTypes.Sum(x => x.SizeOnStack) + 1)); codeDataStream.WriteByte(0); } - else - { + else { Binary.BigEndian.Write(codeDataStream, writerState.ConstantPool.Find(new MethodReferenceEntry( new ClassEntry(new Utf8Entry(methodInstruction.Owner.Name)), new NameAndTypeEntry(new Utf8Entry(methodInstruction.Name), new Utf8Entry(methodInstruction.Descriptor.ToString()))))); } + break; case TypeInstruction typeInstruction: codeDataStream.WriteByte((byte) typeInstruction.Opcode); @@ -879,16 +911,15 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat codeDataStream.WriteByte((byte) Opcode.WIDE); codeDataStream.WriteByte((byte) incrementInstruction.Opcode); if (incrementInstruction.VariableIndex > byte.MaxValue || - incrementInstruction.Value > sbyte.MaxValue || incrementInstruction.Value < sbyte.MinValue) - { + incrementInstruction.Value > sbyte.MaxValue || incrementInstruction.Value < sbyte.MinValue) { Binary.BigEndian.Write(codeDataStream, incrementInstruction.VariableIndex); Binary.BigEndian.Write(codeDataStream, incrementInstruction.Value); } - else - { + else { codeDataStream.WriteByte((byte) incrementInstruction.VariableIndex); codeDataStream.WriteByte(unchecked((byte) incrementInstruction.Value)); } + break; case IntegerPushInstruction integerPushInstruction: codeDataStream.WriteByte((byte) integerPushInstruction.Opcode); @@ -931,19 +962,18 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat default: throw new ArgumentOutOfRangeException(nameof(ldcInstruction.Value), $"Can't encode value of type {ldcInstruction.Value.GetType()}"); } - if (ldcInstruction.Value is long || ldcInstruction.Value is double) - { + if (ldcInstruction.Value is long || ldcInstruction.Value is double) { codeDataStream.WriteByte((byte) Opcode.LDC2_W); Binary.BigEndian.Write(codeDataStream, constantPoolEntryIndex); } - else - { + else { codeDataStream.WriteByte((byte) (constantPoolEntryIndex > byte.MaxValue ? Opcode.LDC_W : Opcode.LDC)); if (constantPoolEntryIndex > byte.MaxValue) Binary.BigEndian.Write(codeDataStream, constantPoolEntryIndex); else codeDataStream.WriteByte((byte) constantPoolEntryIndex); } + break; case LookupSwitchInstruction lookupSwitchInstruction: codeDataStream.WriteByte((byte) lookupSwitchInstruction.Opcode); @@ -951,11 +981,11 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat codeDataStream.WriteByte(0); Binary.BigEndian.Write(codeDataStream, instructions[lookupSwitchInstruction.Default] - position); Binary.BigEndian.Write(codeDataStream, lookupSwitchInstruction.MatchLabels.Count); - foreach (KeyValuePair pair in lookupSwitchInstruction.MatchLabels) - { + foreach (KeyValuePair pair in lookupSwitchInstruction.MatchLabels) { Binary.BigEndian.Write(codeDataStream, pair.Key); Binary.BigEndian.Write(codeDataStream, instructions[pair.Value] - position); } + break; case MultiANewArrayInstruction multiANewArrayInstruction: codeDataStream.WriteByte((byte) multiANewArrayInstruction.Opcode); @@ -983,11 +1013,9 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat Binary.BigEndian.Write(codeDataStream, instructions[label] - position); break; case VariableInstruction variableInstruction: - if (variableInstruction.Opcode != Opcode.RET && variableInstruction.VariableIndex < 4) - { + if (variableInstruction.Opcode != Opcode.RET && variableInstruction.VariableIndex < 4) { // ReSharper disable once SwitchStatementMissingSomeCases - switch (variableInstruction.Opcode) - { + switch (variableInstruction.Opcode) { case Opcode.ASTORE: codeDataStream.WriteByte((byte) ((byte) Opcode.ASTORE_0 + variableInstruction.VariableIndex)); break; @@ -1018,12 +1046,10 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat case Opcode.LLOAD: codeDataStream.WriteByte((byte) ((byte) Opcode.LLOAD_0 + variableInstruction.VariableIndex)); break; - default: - throw new ArgumentOutOfRangeException(nameof(variableInstruction.Opcode)); + default: throw new ArgumentOutOfRangeException(nameof(variableInstruction.Opcode)); } } - else - { + else { if (variableInstruction.VariableIndex > byte.MaxValue) codeDataStream.WriteByte((byte) Opcode.WIDE); codeDataStream.WriteByte((byte) variableInstruction.Opcode); @@ -1032,6 +1058,7 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat else codeDataStream.WriteByte((byte) variableInstruction.VariableIndex); } + break; case InvokeDynamicInstruction invokeDynamicInstruction: codeDataStream.WriteByte((byte) invokeDynamicInstruction.Opcode); @@ -1041,85 +1068,73 @@ public static CodeAttribute SaveCodeAttribute(MethodNode source, ClassWriterStat BootstrapMethod bootstrapMethod = new BootstrapMethod(invokeDynamicInstruction.BootstrapMethod, invokeDynamicInstruction.BootstrapMethodArgs); Binary.BigEndian.Write(codeDataStream, writerState.ConstantPool.Find(new InvokeDynamicEntry( - (ushort) bootstrapMethodAttribute.BootstrapMethods.FindIndex(x => x.Equals(bootstrapMethod)), - new NameAndTypeEntry(new Utf8Entry(invokeDynamicInstruction.Name), - new Utf8Entry(invokeDynamicInstruction.Descriptor.ToString()))))); + (ushort) bootstrapMethodAttribute.BootstrapMethods.FindIndex(x => x.Equals(bootstrapMethod)), + new NameAndTypeEntry(new Utf8Entry(invokeDynamicInstruction.Name), + new Utf8Entry(invokeDynamicInstruction.Descriptor.ToString()))))); Binary.BigEndian.Write(codeDataStream, (ushort) 0); break; case StackMapFrame stackMapFrame: - StackMapTableAttribute.VerificationElement ConvertVerificationElement( - VerificationElement sourceVerificationElement) - { + StackMapTableAttribute.VerificationElement ConvertVerificationElement(VerificationElement sourceVerificationElement) { StackMapTableAttribute.VerificationElement verificationElement; - switch (sourceVerificationElement) - { + switch (sourceVerificationElement) { case ObjectVerificationElement objectVerificationElement: - verificationElement = new StackMapTableAttribute.ObjectVerificationElement - { + verificationElement = new StackMapTableAttribute.ObjectVerificationElement { ObjectClass = objectVerificationElement.ObjectClass }; break; case SimpleVerificationElement simpleVerificationElement: verificationElement = new StackMapTableAttribute.SimpleVerificationElement( - (StackMapTableAttribute.VerificationElementType) simpleVerificationElement.Type); + (StackMapTableAttribute.VerificationElementType) simpleVerificationElement.Type); break; case UninitializedVerificationElement uninitializedVerificationElement: if (uninitializedVerificationElement.NewInstruction.Opcode != Opcode.NEW) throw new ArgumentOutOfRangeException(nameof(uninitializedVerificationElement.NewInstruction), $"New instruction is not NEW: {uninitializedVerificationElement.NewInstruction.Opcode}"); - verificationElement = new StackMapTableAttribute.UninitializedVerificationElement - { + verificationElement = new StackMapTableAttribute.UninitializedVerificationElement { NewInstructionOffset = instructions[uninitializedVerificationElement.NewInstruction] }; break; - default: - throw new ArgumentOutOfRangeException(nameof(sourceVerificationElement)); + default: throw new ArgumentOutOfRangeException(nameof(sourceVerificationElement)); } + return verificationElement; } StackMapTableAttribute.StackMapFrame stackMapTableEntry; - switch (stackMapFrame.Type) - { + switch (stackMapFrame.Type) { case FrameType.Same: - stackMapTableEntry = new StackMapTableAttribute.StackMapFrame - { + stackMapTableEntry = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.Same }; break; case FrameType.SameLocals1StackItem: - stackMapTableEntry = new StackMapTableAttribute.StackMapFrame - { + stackMapTableEntry = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.SameLocals1StackItem }; stackMapTableEntry.Stack.Add(ConvertVerificationElement(stackMapFrame.Stack[0])); break; case FrameType.Chop: - stackMapTableEntry = new StackMapTableAttribute.StackMapFrame - { + stackMapTableEntry = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.Chop, ChopK = stackMapFrame.ChopK }; break; case FrameType.Append: - stackMapTableEntry = new StackMapTableAttribute.StackMapFrame - { + stackMapTableEntry = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.Append }; stackMapTableEntry.Locals.AddRange(stackMapFrame.Locals.Select(ConvertVerificationElement)); break; case FrameType.Full: - stackMapTableEntry = new StackMapTableAttribute.StackMapFrame - { + stackMapTableEntry = new StackMapTableAttribute.StackMapFrame { Type = StackMapTableAttribute.FrameType.Full }; stackMapTableEntry.Locals.AddRange(stackMapFrame.Locals.Select(ConvertVerificationElement)); stackMapTableEntry.Stack.AddRange(stackMapFrame.Stack.Select(ConvertVerificationElement)); break; - default: - throw new ArgumentOutOfRangeException(nameof(stackMapFrame.Type)); + default: throw new ArgumentOutOfRangeException(nameof(stackMapFrame.Type)); } if (position - previousStackMapFramePosition <= 0) @@ -1132,20 +1147,16 @@ StackMapTableAttribute.VerificationElement ConvertVerificationElement( case LineNumber _: case Label _: break; - default: - throw new ArgumentOutOfRangeException(nameof(instruction)); + default: throw new ArgumentOutOfRangeException(nameof(instruction)); } } - if (stackMapFrames.Count > 0) - { + if (stackMapFrames.Count > 0) { if (codeAttribute.Attributes.Any(x => x.Name == PredefinedAttributeNames.StackMapTable)) throw new ArgumentException($"There is already a {PredefinedAttributeNames.StackMapTable} attribute"); - codeAttribute.Attributes.Add(new AttributeNode - { + codeAttribute.Attributes.Add(new AttributeNode { Name = PredefinedAttributeNames.StackMapTable, - ParsedAttribute = new StackMapTableAttribute - { + ParsedAttribute = new StackMapTableAttribute { Entries = stackMapFrames } }); @@ -1156,4 +1167,4 @@ StackMapTableAttribute.VerificationElement ConvertVerificationElement( return codeAttribute; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Opcode.cs b/JavaAsm/Instructions/Opcode.cs index 040f9cd..5771e8c 100644 --- a/JavaAsm/Instructions/Opcode.cs +++ b/JavaAsm/Instructions/Opcode.cs @@ -1,10 +1,8 @@ using System.Diagnostics.CodeAnalysis; -namespace JavaAsm.Instructions -{ +namespace JavaAsm.Instructions { [SuppressMessage("ReSharper", "InconsistentNaming")] - public enum Opcode : byte - { + public enum Opcode : byte { None = 0xFF, AALOAD = 0x32, @@ -211,4 +209,4 @@ public enum Opcode : byte TABLESWITCH = 0xAA, WIDE = 0xC4 } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/IncrementInstruction.cs b/JavaAsm/Instructions/Types/IncrementInstruction.cs index a6a3e03..d9abdef 100644 --- a/JavaAsm/Instructions/Types/IncrementInstruction.cs +++ b/JavaAsm/Instructions/Types/IncrementInstruction.cs @@ -1,9 +1,7 @@ using System; -namespace JavaAsm.Instructions.Types -{ - public class IncrementInstruction : Instruction - { +namespace JavaAsm.Instructions.Types { + public class IncrementInstruction : Instruction { public override Opcode Opcode { get => Opcode.IINC; set => throw new InvalidOperationException(GetType().Name + " only has 1 opcode"); @@ -13,9 +11,8 @@ public override Opcode Opcode { public short Value { get; set; } - public override string ToString() - { + public override string ToString() { return $"{this.Opcode} {this.VariableIndex} {this.Value}"; } } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/NewArrayInstruction.cs b/JavaAsm/Instructions/Types/NewArrayInstruction.cs index 0d252e5..8f735e4 100644 --- a/JavaAsm/Instructions/Types/NewArrayInstruction.cs +++ b/JavaAsm/Instructions/Types/NewArrayInstruction.cs @@ -1,9 +1,7 @@ using System; -namespace JavaAsm.Instructions.Types -{ - public class NewArrayInstruction : Instruction - { +namespace JavaAsm.Instructions.Types { + public class NewArrayInstruction : Instruction { public override Opcode Opcode { get => Opcode.NEWARRAY; set => throw new InvalidOperationException(GetType().Name + " only has 1 instruction"); @@ -11,14 +9,12 @@ public override Opcode Opcode { public NewArrayTypeCode ArrayType { get; set; } - public override string ToString() - { + public override string ToString() { return $"{this.Opcode} {this.ArrayType}"; } } - public enum NewArrayTypeCode : byte - { + public enum NewArrayTypeCode : byte { Boolean = 4, Character, Float, @@ -28,4 +24,4 @@ public enum NewArrayTypeCode : byte Integer, Long } -} +} \ No newline at end of file diff --git a/JavaAsm/Instructions/Types/TableSwitchInstruction.cs b/JavaAsm/Instructions/Types/TableSwitchInstruction.cs index f1ca275..9be3900 100644 --- a/JavaAsm/Instructions/Types/TableSwitchInstruction.cs +++ b/JavaAsm/Instructions/Types/TableSwitchInstruction.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; -namespace JavaAsm.Instructions.Types -{ - public class TableSwitchInstruction : Instruction - { +namespace JavaAsm.Instructions.Types { + public class TableSwitchInstruction : Instruction { public override Opcode Opcode { get => Opcode.TABLESWITCH; set => throw new InvalidOperationException(GetType().Name + " only has 1 opcode"); @@ -18,4 +16,4 @@ public override Opcode Opcode { public List