├── .github ├── dependabot.yml └── workflows │ └── maven.yml ├── .gitignore ├── .gitmodules ├── COPYING.txt ├── LICENSE.txt ├── README.md ├── pom.xml ├── process-patch.pl ├── src ├── main │ └── java │ │ ├── io │ │ └── github │ │ │ └── dmlloyd │ │ │ └── classfile │ │ │ ├── AccessFlags.java │ │ │ ├── Annotation.java │ │ │ ├── AnnotationElement.java │ │ │ ├── AnnotationValue.java │ │ │ ├── Attribute.java │ │ │ ├── AttributeMapper.java │ │ │ ├── AttributedElement.java │ │ │ ├── Attributes.java │ │ │ ├── BootstrapMethodEntry.java │ │ │ ├── BufWriter.java │ │ │ ├── ClassBuilder.java │ │ │ ├── ClassElement.java │ │ │ ├── ClassFile.java │ │ │ ├── ClassFileBuilder.java │ │ │ ├── ClassFileElement.java │ │ │ ├── ClassFileTransform.java │ │ │ ├── ClassFileVersion.java │ │ │ ├── ClassHierarchyResolver.java │ │ │ ├── ClassModel.java │ │ │ ├── ClassReader.java │ │ │ ├── ClassSignature.java │ │ │ ├── ClassTransform.java │ │ │ ├── CodeBuilder.java │ │ │ ├── CodeElement.java │ │ │ ├── CodeModel.java │ │ │ ├── CodeTransform.java │ │ │ ├── CompoundElement.java │ │ │ ├── CustomAttribute.java │ │ │ ├── FieldBuilder.java │ │ │ ├── FieldElement.java │ │ │ ├── FieldModel.java │ │ │ ├── FieldTransform.java │ │ │ ├── Instruction.java │ │ │ ├── Interfaces.java │ │ │ ├── Label.java │ │ │ ├── MethodBuilder.java │ │ │ ├── MethodElement.java │ │ │ ├── MethodModel.java │ │ │ ├── MethodSignature.java │ │ │ ├── MethodTransform.java │ │ │ ├── Opcode.java │ │ │ ├── PseudoInstruction.java │ │ │ ├── Signature.java │ │ │ ├── Superclass.java │ │ │ ├── TypeAnnotation.java │ │ │ ├── TypeKind.java │ │ │ ├── attribute │ │ │ ├── AnnotationDefaultAttribute.java │ │ │ ├── BootstrapMethodsAttribute.java │ │ │ ├── CharacterRangeInfo.java │ │ │ ├── CharacterRangeTableAttribute.java │ │ │ ├── CodeAttribute.java │ │ │ ├── CompilationIDAttribute.java │ │ │ ├── ConstantValueAttribute.java │ │ │ ├── DeprecatedAttribute.java │ │ │ ├── EnclosingMethodAttribute.java │ │ │ ├── ExceptionsAttribute.java │ │ │ ├── InnerClassInfo.java │ │ │ ├── InnerClassesAttribute.java │ │ │ ├── LineNumberInfo.java │ │ │ ├── LineNumberTableAttribute.java │ │ │ ├── LocalVariableInfo.java │ │ │ ├── LocalVariableTableAttribute.java │ │ │ ├── LocalVariableTypeInfo.java │ │ │ ├── LocalVariableTypeTableAttribute.java │ │ │ ├── MethodParameterInfo.java │ │ │ ├── MethodParametersAttribute.java │ │ │ ├── ModuleAttribute.java │ │ │ ├── ModuleExportInfo.java │ │ │ ├── ModuleHashInfo.java │ │ │ ├── ModuleHashesAttribute.java │ │ │ ├── ModuleMainClassAttribute.java │ │ │ ├── ModuleOpenInfo.java │ │ │ ├── ModulePackagesAttribute.java │ │ │ ├── ModuleProvideInfo.java │ │ │ ├── ModuleRequireInfo.java │ │ │ ├── ModuleResolutionAttribute.java │ │ │ ├── ModuleTargetAttribute.java │ │ │ ├── NestHostAttribute.java │ │ │ ├── NestMembersAttribute.java │ │ │ ├── PermittedSubclassesAttribute.java │ │ │ ├── RecordAttribute.java │ │ │ ├── RecordComponentInfo.java │ │ │ ├── RuntimeInvisibleAnnotationsAttribute.java │ │ │ ├── RuntimeInvisibleParameterAnnotationsAttribute.java │ │ │ ├── RuntimeInvisibleTypeAnnotationsAttribute.java │ │ │ ├── RuntimeVisibleAnnotationsAttribute.java │ │ │ ├── RuntimeVisibleParameterAnnotationsAttribute.java │ │ │ ├── RuntimeVisibleTypeAnnotationsAttribute.java │ │ │ ├── SignatureAttribute.java │ │ │ ├── SourceDebugExtensionAttribute.java │ │ │ ├── SourceFileAttribute.java │ │ │ ├── SourceIDAttribute.java │ │ │ ├── StackMapFrameInfo.java │ │ │ ├── StackMapTableAttribute.java │ │ │ ├── SyntheticAttribute.java │ │ │ ├── UnknownAttribute.java │ │ │ ├── package-info.java │ │ │ └── snippet-files │ │ │ │ └── PackageSnippets.java │ │ │ ├── components │ │ │ ├── ClassPrinter.java │ │ │ ├── ClassRemapper.java │ │ │ ├── CodeLocalsShifter.java │ │ │ ├── CodeRelabeler.java │ │ │ ├── CodeStackTracker.java │ │ │ ├── package-info.java │ │ │ └── snippet-files │ │ │ │ └── PackageSnippets.java │ │ │ ├── constantpool │ │ │ ├── AnnotationConstantValueEntry.java │ │ │ ├── ClassEntry.java │ │ │ ├── ConstantDynamicEntry.java │ │ │ ├── ConstantPool.java │ │ │ ├── ConstantPoolBuilder.java │ │ │ ├── ConstantPoolException.java │ │ │ ├── ConstantValueEntry.java │ │ │ ├── DoubleEntry.java │ │ │ ├── DynamicConstantPoolEntry.java │ │ │ ├── FieldRefEntry.java │ │ │ ├── FloatEntry.java │ │ │ ├── IntegerEntry.java │ │ │ ├── InterfaceMethodRefEntry.java │ │ │ ├── InvokeDynamicEntry.java │ │ │ ├── LoadableConstantEntry.java │ │ │ ├── LongEntry.java │ │ │ ├── MemberRefEntry.java │ │ │ ├── MethodHandleEntry.java │ │ │ ├── MethodRefEntry.java │ │ │ ├── MethodTypeEntry.java │ │ │ ├── ModuleEntry.java │ │ │ ├── NameAndTypeEntry.java │ │ │ ├── PackageEntry.java │ │ │ ├── PoolEntry.java │ │ │ ├── StringEntry.java │ │ │ ├── Utf8Entry.java │ │ │ ├── package-info.java │ │ │ └── snippet-files │ │ │ │ └── PackageSnippets.java │ │ │ ├── extras │ │ │ ├── PreviewFeature.java │ │ │ ├── constant │ │ │ │ ├── ConstantUtils.java │ │ │ │ ├── ExtraClassDesc.java │ │ │ │ ├── ExtraConstantDescs.java │ │ │ │ ├── ModuleDesc.java │ │ │ │ ├── ModuleDescImpl.java │ │ │ │ ├── PackageDesc.java │ │ │ │ └── PackageDescImpl.java │ │ │ └── reflect │ │ │ │ ├── AccessFlag.java │ │ │ │ └── ClassFileFormatVersion.java │ │ │ ├── impl │ │ │ ├── AbstractAttributeMapper.java │ │ │ ├── AbstractBoundLocalVariable.java │ │ │ ├── AbstractDirectBuilder.java │ │ │ ├── AbstractElement.java │ │ │ ├── AbstractInstruction.java │ │ │ ├── AbstractPoolEntry.java │ │ │ ├── AbstractPseudoInstruction.java │ │ │ ├── AbstractUnboundModel.java │ │ │ ├── AccessFlagsImpl.java │ │ │ ├── AnnotationImpl.java │ │ │ ├── AnnotationReader.java │ │ │ ├── AttributeHolder.java │ │ │ ├── BackportUtil.java │ │ │ ├── BlockCodeBuilderImpl.java │ │ │ ├── BootstrapMethodEntryImpl.java │ │ │ ├── BoundAttribute.java │ │ │ ├── BoundCharacterRange.java │ │ │ ├── BoundLocalVariable.java │ │ │ ├── BoundLocalVariableType.java │ │ │ ├── BoundRecordComponentInfo.java │ │ │ ├── BufWriterImpl.java │ │ │ ├── BufferedCodeBuilder.java │ │ │ ├── BufferedFieldBuilder.java │ │ │ ├── BufferedMethodBuilder.java │ │ │ ├── BytecodeHelpers.java │ │ │ ├── CatchBuilderImpl.java │ │ │ ├── ChainedClassBuilder.java │ │ │ ├── ChainedCodeBuilder.java │ │ │ ├── ChainedFieldBuilder.java │ │ │ ├── ChainedMethodBuilder.java │ │ │ ├── ClassFileImpl.java │ │ │ ├── ClassFileVersionImpl.java │ │ │ ├── ClassHierarchyImpl.java │ │ │ ├── ClassImpl.java │ │ │ ├── ClassPrinterImpl.java │ │ │ ├── ClassReaderImpl.java │ │ │ ├── ClassRemapperImpl.java │ │ │ ├── CodeImpl.java │ │ │ ├── CodeLocalsShifterImpl.java │ │ │ ├── CodeRelabelerImpl.java │ │ │ ├── CodeStackTrackerImpl.java │ │ │ ├── DirectClassBuilder.java │ │ │ ├── DirectCodeBuilder.java │ │ │ ├── DirectFieldBuilder.java │ │ │ ├── DirectMethodBuilder.java │ │ │ ├── EntryMap.java │ │ │ ├── FieldImpl.java │ │ │ ├── InterfacesImpl.java │ │ │ ├── LabelContext.java │ │ │ ├── LabelImpl.java │ │ │ ├── LineNumberImpl.java │ │ │ ├── MethodImpl.java │ │ │ ├── MethodInfo.java │ │ │ ├── ModuleAttributeBuilderImpl.java │ │ │ ├── NonterminalCodeBuilder.java │ │ │ ├── RawBytecodeHelper.java │ │ │ ├── SignaturesImpl.java │ │ │ ├── SplitConstantPool.java │ │ │ ├── StackCounter.java │ │ │ ├── StackMapDecoder.java │ │ │ ├── StackMapGenerator.java │ │ │ ├── SuperclassImpl.java │ │ │ ├── TargetInfoImpl.java │ │ │ ├── TemporaryConstantPool.java │ │ │ ├── TerminalCodeBuilder.java │ │ │ ├── TerminalFieldBuilder.java │ │ │ ├── TerminalMethodBuilder.java │ │ │ ├── TransformImpl.java │ │ │ ├── UnboundAttribute.java │ │ │ ├── Util.java │ │ │ └── verifier │ │ │ │ ├── ParserVerifier.java │ │ │ │ ├── VerificationBytecodes.java │ │ │ │ ├── VerificationFrame.java │ │ │ │ ├── VerificationSignature.java │ │ │ │ ├── VerificationTable.java │ │ │ │ ├── VerificationType.java │ │ │ │ ├── VerificationWrapper.java │ │ │ │ └── VerifierImpl.java │ │ │ ├── instruction │ │ │ ├── ArrayLoadInstruction.java │ │ │ ├── ArrayStoreInstruction.java │ │ │ ├── BranchInstruction.java │ │ │ ├── CharacterRange.java │ │ │ ├── ConstantInstruction.java │ │ │ ├── ConvertInstruction.java │ │ │ ├── DiscontinuedInstruction.java │ │ │ ├── ExceptionCatch.java │ │ │ ├── FieldInstruction.java │ │ │ ├── IncrementInstruction.java │ │ │ ├── InvokeDynamicInstruction.java │ │ │ ├── InvokeInstruction.java │ │ │ ├── LabelTarget.java │ │ │ ├── LineNumber.java │ │ │ ├── LoadInstruction.java │ │ │ ├── LocalVariable.java │ │ │ ├── LocalVariableType.java │ │ │ ├── LookupSwitchInstruction.java │ │ │ ├── MonitorInstruction.java │ │ │ ├── NewMultiArrayInstruction.java │ │ │ ├── NewObjectInstruction.java │ │ │ ├── NewPrimitiveArrayInstruction.java │ │ │ ├── NewReferenceArrayInstruction.java │ │ │ ├── NopInstruction.java │ │ │ ├── OperatorInstruction.java │ │ │ ├── ReturnInstruction.java │ │ │ ├── StackInstruction.java │ │ │ ├── StoreInstruction.java │ │ │ ├── SwitchCase.java │ │ │ ├── TableSwitchInstruction.java │ │ │ ├── ThrowInstruction.java │ │ │ ├── TypeCheckInstruction.java │ │ │ └── package-info.java │ │ │ ├── package-info.java │ │ │ └── snippet-files │ │ │ └── PackageSnippets.java │ │ └── module-info.java └── test │ └── java │ └── io │ └── github │ └── dmlloyd │ └── classfile │ └── tests │ └── SimpleTests.java └── utils └── ProcessPatch.java /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" # Location of package manifests 5 | schedule: 6 | interval: "daily" 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "daily" 11 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | paths-ignore: 5 | - '**.md' 6 | - '**.adoc' 7 | branches: [ main ] 8 | types: [ opened, synchronize, reopened ] 9 | jobs: 10 | build: 11 | name: "Build and test" 12 | runs-on: ubuntu-latest 13 | continue-on-error: true 14 | steps: 15 | - name: Install OpenJDK 16 | uses: actions/setup-java@v4 17 | with: 18 | java-version: '17' 19 | distribution: 'temurin' 20 | 21 | - name: Clone project 22 | uses: actions/checkout@v4 23 | with: 24 | path: jdk-classfile-backport 25 | 26 | - name: Build 27 | run: | 28 | mvn --batch-mode verify 29 | working-directory: jdk-classfile-backport 30 | 31 | - name: Prepare failure archive (if maven failed) 32 | if: failure() 33 | shell: bash 34 | run: find . -type d -name '*-reports' -o -name "*-logs" | tar -czf test-reports.tgz -T - 35 | 36 | - name: Upload failure Archive (if maven failed) 37 | uses: actions/upload-artifact@v4 38 | if: failure() 39 | with: 40 | name: test-reports 41 | path: | 42 | 'test-reports.tgz' 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .classpath 3 | .settings 4 | *.iml 5 | target 6 | .idea 7 | .vscode 8 | *.ipr 9 | *~ 10 | out 11 | a.out 12 | *.o 13 | *.s 14 | *.ll 15 | *.bc 16 | .factorypath 17 | *.dot 18 | *.svg 19 | *.class 20 | *.jar 21 | *.versionsBackup 22 | hs_err*.log 23 | .mvn 24 | *.orig 25 | *.rej 26 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "jdk"] 2 | path = jdk 3 | url = git@github.com:openjdk/jdk 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Except where otherwise indicated, the software in this project is 2 | licensed under the GNU General Public License, version 2 (see the file 3 | named COPYING), along with the Classpath Exception: 4 | 5 | Linking this library statically or dynamically with other modules is 6 | making a combined work based on this library. Thus, the terms and 7 | conditions of the GNU General Public License cover the whole 8 | combination. 9 | 10 | As a special exception, the copyright holders of this library give you 11 | permission to link this library with independent modules to produce an 12 | executable, regardless of the license terms of these independent 13 | modules, and to copy and distribute the resulting executable under 14 | terms of your choice, provided that you also meet, for each linked 15 | independent module, the terms and conditions of the license of that 16 | module. An independent module is a module which is not derived from 17 | or based on this library. If you modify this library, you may extend 18 | this exception to your version of the library, but you are not 19 | obligated to do so. If you do not wish to do so, delete this 20 | exception statement from your version. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Unofficial JDK Classfile API Backport 2 | ======== 3 | 4 | [![Maven Central](https://img.shields.io/maven-central/v/io.github.dmlloyd/jdk-classfile-backport?color=green)](https://search.maven.org/search?q=g:io.github.dmlloyd%20AND%20a:jdk-classfile-backport) 5 | 6 | This is a backport to JDK 17 of the new classfile API found in JDK 21 and later. 7 | 8 | Bugs in this project should be reported to [the GitHub issue tracker](https://github.com/dmlloyd/jdk-classfile-backport/issues) first. Bugs in this project are likely to be a result of backporting. Some bugs might be relayed upstream by the project maintainer(s), subject to testing and verification; in this case, the upstream bug will be linked for easier tracking. 9 | 10 | Releases 11 | -------- 12 | 13 | Releases of the project roughly track releases of the corresponding JDK from which it is backported. This means that version 24.x of this project corresponds to the state of the upstream classfile API in JDK 24, and so on. 14 | 15 | Binary compatibility is maintained with a strictness corresponding to that of the upstream API. 16 | 17 | It is currently planned to continue to backport features indefinitely. The major version of this project will continue to correspond to the JDK from which the changes were backported. When planning a transition from this library to the official API, be sure that the major version of this library corresponds to the target JDK to avoid a situation where you start using features which are not available in the JDK version you want to target, causing difficulties when migrating. 18 | 19 | The release schedule is fairly ad-hoc and irregular, but will generally align with that of the upstream JDK. If you encounter a bug which has been fixed in this project but not yet released, feel free to open an issue to request a release. 20 | 21 | Getting started 22 | --------------- 23 | 24 | After adding the appropriate Maven dependency (see the Maven release badge above), the easiest entry points are: 25 | 26 | For parsing a class: 27 | 28 | ```java 29 | byte[] b = Files.readAllBytes(Path.of("some/file.class")); 30 | ClassModel model = ClassFile.of().parse(b); 31 | // now, do something with `model`... 32 | ``` 33 | 34 | Or for writing a class: 35 | 36 | ```java 37 | byte[] b = ClassFile.of().build(classDesc, classBuilder -> { 38 | // ... build the class here ... 39 | }); 40 | ``` 41 | More information 42 | ---------------- 43 | 44 | For more information on this API, see: 45 | 46 | * [JEP 484](https://openjdk.org/jeps/484) 47 | * [The official upstream documentation at Oracle](https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/lang/classfile/package-summary.html) 48 | -------------------------------------------------------------------------------- /process-patch.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | chdir "jdk"; 7 | 8 | my $usage = "Usage: $0 "; 9 | 10 | my $from = shift @ARGV or die $usage; 11 | my $to = shift @ARGV or die $usage; 12 | 13 | open my $git_fh, "-|", "git", "diff", "-M75", $from."..".$to, "--", 14 | "src/java.base/share/classes/java/lang/classfile", 15 | "src/java.base/share/classes/jdk/internal/classfile", 16 | "src/java.base/share/classes/java/lang/reflect/AccessFlag.java", 17 | "src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java", 18 | "src/java.base/share/classes/java/lang/constant/ModuleDesc.java", 19 | "src/java.base/share/classes/java/lang/constant/PackageDesc.java", 20 | "src/java.base/share/classes/jdk/internal/constant/ConstantUtils.java", 21 | "src/java.base/share/classes/jdk/internal/constant/ModuleDescImpl.java", 22 | "src/java.base/share/classes/jdk/internal/constant/PackageDescImpl.java" 23 | or die "Failed to run git: $?"; 24 | 25 | while ($_ = <$git_fh>) { 26 | s[jdk\.internal\.javac\.PreviewFeature][io.github.dmlloyd.classfile.extras.PreviewFeature]g; 27 | s[java(.)lang.reflect.(AccessFlag|ClassFileFormatVersion)][io$1github$1dmlloyd$1classfile$1extras$1reflect$1$2]g; 28 | s[java(.)lang.constant.(ModuleDesc|PackageDesc)][io$1github$1dmlloyd$1classfile$1extras$1constant$1$2]g; 29 | s[jdk(.)internal.constant.(ModuleDescImpl|PackageDescImpl|ConstantUtils)][io$1github$1dmlloyd$1classfile$1extras$1constant$1$2]g; 30 | s[ConstantDescs\.INIT_NAME][ExtraConstantDescs.INIT_NAME]g; 31 | s[ConstantDescs\.CLASS_INIT_NAME][ExtraConstantDescs.CLASS_INIT_NAME]g; 32 | s[ClassDesc\.ofInternalName][ExtraClassDesc.ofInternalName]g; 33 | s[java(.)lang.classfile][io$1github$1dmlloyd$1classfile]g; 34 | s[jdk(.)internal.classfile][io$1github$1dmlloyd$1classfile]g; 35 | s[(import jdk\.internal\.constant\.(ReferenceClass|PrimitiveClass|ClassOrInterface)DescImpl.*)][//$1]g; 36 | s[jdk(.)internal.constant][io$1github$1dmlloyd$1classfile$1extras$1constant]g; 37 | s[package java\.lang\.reflect][package io.github.dmlloyd.classfile.extras.reflect]g; 38 | s[package java\.lang\.constant][package io.github.dmlloyd.classfile.extras.constant]g; 39 | s[src/java\.base/share/classes][src/main/java]g; 40 | s[(import jdk\.internal\..*)][//$1]g; 41 | s[(import sun\..*)][//$1]g; 42 | print $_; 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/ClassElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile; 26 | 27 | import io.github.dmlloyd.classfile.attribute.*; 28 | 29 | /** 30 | * Marker interface for a member element of a {@link ClassModel}. Such an 31 | * element can appear when traversing a {@link ClassModel} unless otherwise 32 | * specified, be supplied to a {@link ClassBuilder}, and be processed by a 33 | * {@link ClassTransform}. 34 | *

35 | * {@link AccessFlags}, and {@link ClassFileVersion} are member elements of a 36 | * class that appear exactly once during the traversal of a {@link ClassModel}. 37 | * {@link Superclass} and {@link Interfaces} may be absent or appear at most 38 | * once. A {@link ClassBuilder} may provide an alternative superclass if it is 39 | * not defined but required. 40 | * 41 | * @see ClassFileElement##membership Membership Elements 42 | * @see MethodElement 43 | * @see FieldElement 44 | * @see CodeElement 45 | * @sealedGraph 46 | * @since 24 47 | */ 48 | public sealed interface ClassElement extends ClassFileElement 49 | permits AccessFlags, Superclass, Interfaces, ClassFileVersion, 50 | FieldModel, MethodModel, 51 | CustomAttribute, CompilationIDAttribute, DeprecatedAttribute, 52 | EnclosingMethodAttribute, InnerClassesAttribute, 53 | ModuleAttribute, ModuleHashesAttribute, ModuleMainClassAttribute, 54 | ModulePackagesAttribute, ModuleResolutionAttribute, ModuleTargetAttribute, 55 | NestHostAttribute, NestMembersAttribute, PermittedSubclassesAttribute, 56 | RecordAttribute, 57 | RuntimeInvisibleAnnotationsAttribute, RuntimeInvisibleTypeAnnotationsAttribute, 58 | RuntimeVisibleAnnotationsAttribute, RuntimeVisibleTypeAnnotationsAttribute, 59 | SignatureAttribute, SourceDebugExtensionAttribute, 60 | SourceFileAttribute, SourceIDAttribute, SyntheticAttribute, UnknownAttribute { 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/ClassFileElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile; 26 | 27 | /** 28 | * Marker interface for structures with special capabilities in the {@code 29 | * class} file format. {@link AttributedElement} indicates a structure has 30 | * {@link Attribute}s. {@link CompoundElement} indicates a structure can be 31 | * viewed as a composition of member structures, whose memberships are marked by 32 | * {@link ClassElement}, {@link MethodElement}, {@link FieldElement}, or {@link 33 | * CodeElement}. 34 | * 35 | *

Membership Elements

36 | * {@link ClassModel}, {@link MethodModel}, {@link FieldModel}, and {@link 37 | * CodeModel} each has a dedicated interface marking its member structures: 38 | * {@link ClassElement}, {@link MethodElement}, {@link FieldElement}, and 39 | * {@link CodeElement}. They can be supplied to a {@link ClassBuilder}, a 40 | * {@link MethodBuilder}, a {@link FieldBuilder}, or a {@link CodeBuilder} to be 41 | * included as members of the built model. Unless otherwise specified, these 42 | * structures are delivered during the {@linkplain CompoundElement traversal} of 43 | * the corresponding models. Some of these elements may appear at most once or 44 | * exactly once in the traversal of the models; such elements have special 45 | * treatment by {@link ClassFileBuilder} and are specified in their modeling 46 | * interfaces. If such elements appear multiple times during traversal, the 47 | * last occurrence should be used and all previous instances should be 48 | * discarded. 49 | *

50 | * These membership element marker interfaces are sealed; future versions of the 51 | * Java SE Platform may define new elements to the sealed hierarchy when the 52 | * {@code class} file format for the Java Platform evolves. Using an exhaustive 53 | * pattern matching switch over these hierarchies indicates the user only wish 54 | * the processing code to run on a specific version of Java Platform, and will 55 | * fail if unknown new elements are encountered. 56 | * 57 | * @sealedGraph 58 | * @since 24 59 | */ 60 | public sealed interface ClassFileElement 61 | permits AttributedElement, CompoundElement, Attribute, 62 | ClassElement, CodeElement, FieldElement, MethodElement { 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/CodeElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile; 26 | 27 | import io.github.dmlloyd.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute; 28 | import io.github.dmlloyd.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute; 29 | import io.github.dmlloyd.classfile.attribute.StackMapTableAttribute; 30 | import io.github.dmlloyd.classfile.attribute.UnknownAttribute; 31 | 32 | /** 33 | * Marker interface for a member element of a {@link CodeModel}. Such an 34 | * element can appear when traversing a {@link CodeModel} unless otherwise 35 | * specified, be supplied to a {@link CodeBuilder}, and be processed by a 36 | * {@link CodeTransform}. 37 | *

38 | * Code elements can be categorized into {@link Instruction}, {@link 39 | * PseudoInstruction}, and {@link Attribute}. Unlike in other {@link 40 | * CompoundElement}, the order of elements for all {@link Instruction}s and some 41 | * {@link PseudoInstruction}s is significant. 42 | * 43 | * @see ClassFileElement##membership Membership Elements 44 | * @see ClassElement 45 | * @see MethodElement 46 | * @see FieldElement 47 | * @sealedGraph 48 | * @since 24 49 | */ 50 | public sealed interface CodeElement extends ClassFileElement 51 | permits Instruction, PseudoInstruction, 52 | CustomAttribute, RuntimeVisibleTypeAnnotationsAttribute, RuntimeInvisibleTypeAnnotationsAttribute, 53 | StackMapTableAttribute, UnknownAttribute { 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/FieldBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile; 27 | 28 | import java.lang.constant.ClassDesc; 29 | import io.github.dmlloyd.classfile.extras.reflect.AccessFlag; 30 | import java.util.function.Consumer; 31 | 32 | import io.github.dmlloyd.classfile.impl.AccessFlagsImpl; 33 | import io.github.dmlloyd.classfile.impl.ChainedFieldBuilder; 34 | import io.github.dmlloyd.classfile.impl.TerminalFieldBuilder; 35 | 36 | /** 37 | * A builder for fields. The main way to obtain a field builder is via {@link 38 | * ClassBuilder#withField(String, ClassDesc, Consumer)}. The {@linkplain 39 | * ClassBuilder#withField(String, ClassDesc, int) access flag overload} is 40 | * useful if no attribute needs to be configured, skipping the handler. 41 | *

42 | * Refer to {@link ClassFileBuilder} for general guidance and caution around 43 | * the use of builders for structures in the {@code class} file format. 44 | * 45 | * @see ClassBuilder#withField(String, ClassDesc, Consumer) 46 | * @see FieldModel 47 | * @see FieldTransform 48 | * @since 24 49 | */ 50 | public sealed interface FieldBuilder 51 | extends ClassFileBuilder 52 | permits TerminalFieldBuilder, ChainedFieldBuilder { 53 | 54 | /** 55 | * Sets the field access flags. 56 | * 57 | * @param flags the access flags, as a bit mask 58 | * @return this builder 59 | * @see AccessFlags 60 | * @see AccessFlag.Location#FIELD 61 | * @see ClassBuilder#withField(String, ClassDesc, int) 62 | */ 63 | default FieldBuilder withFlags(int flags) { 64 | return with(new AccessFlagsImpl(AccessFlag.Location.FIELD, flags)); 65 | } 66 | 67 | /** 68 | * Sets the field access flags. 69 | * 70 | * @param flags the access flags, as a bit mask 71 | * @return this builder 72 | * @see AccessFlags 73 | * @see AccessFlag.Location#FIELD 74 | * @see ClassBuilder#withField(String, ClassDesc, int) 75 | */ 76 | default FieldBuilder withFlags(AccessFlag... flags) { 77 | return with(new AccessFlagsImpl(AccessFlag.Location.FIELD, flags)); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/FieldElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile; 26 | 27 | import io.github.dmlloyd.classfile.attribute.*; 28 | 29 | /** 30 | * Marker interface for a member element of a {@link FieldModel}. Such an 31 | * element can appear when traversing a {@link FieldModel} unless otherwise 32 | * specified, be supplied to a {@link FieldBuilder}, and be processed by a 33 | * {@link FieldTransform}. 34 | *

35 | * {@link AccessFlags} is the only member element of a field that appear exactly 36 | * once during the traversal of a {@link FieldModel}. 37 | * 38 | * @see ClassFileElement##membership Membership Elements 39 | * @see ClassElement 40 | * @see MethodElement 41 | * @see CodeElement 42 | * @sealedGraph 43 | * @since 24 44 | */ 45 | public sealed interface FieldElement extends ClassFileElement 46 | permits AccessFlags, 47 | CustomAttribute, ConstantValueAttribute, DeprecatedAttribute, 48 | RuntimeInvisibleAnnotationsAttribute, RuntimeInvisibleTypeAnnotationsAttribute, 49 | RuntimeVisibleAnnotationsAttribute, RuntimeVisibleTypeAnnotationsAttribute, 50 | SignatureAttribute, SyntheticAttribute, UnknownAttribute { 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/FieldModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile; 27 | 28 | import io.github.dmlloyd.classfile.constantpool.Utf8Entry; 29 | import java.lang.constant.ClassDesc; 30 | import io.github.dmlloyd.classfile.extras.reflect.AccessFlag; 31 | import java.util.Optional; 32 | import java.util.function.Consumer; 33 | 34 | import io.github.dmlloyd.classfile.impl.BufferedFieldBuilder; 35 | import io.github.dmlloyd.classfile.impl.FieldImpl; 36 | import io.github.dmlloyd.classfile.impl.Util; 37 | 38 | /** 39 | * Models a field. A field can be viewed as a {@linkplain CompoundElement 40 | * composition} of {@link FieldElement}s, or by random access via accessor 41 | * methods if only specific parts of the field is needed. 42 | *

43 | * Fields can be obtained from {@link ClassModel#fields()}, or in the traversal 44 | * of member elements of a class. 45 | *

46 | * {@link ClassBuilder#withField(String, ClassDesc, Consumer)} is the main way 47 | * to construct fields. {@link ClassBuilder#transformField} allows creating a 48 | * new field by selectively processing the original field elements and directing 49 | * the results to a field builder. 50 | *

51 | * All field attributes are accessible as member elements. 52 | * 53 | * @see ClassModel#fields() 54 | * @see FieldTransform 55 | * @jvms 4.5 Fields 56 | * @since 24 57 | */ 58 | public sealed interface FieldModel 59 | extends CompoundElement, AttributedElement, ClassElement 60 | permits BufferedFieldBuilder.Model, FieldImpl { 61 | 62 | /** 63 | * {@return the access flags} 64 | * 65 | * @see AccessFlag.Location#FIELD 66 | */ 67 | AccessFlags flags(); 68 | 69 | /** {@return the class model this field is a member of, if known} */ 70 | Optional parent(); 71 | 72 | /** {@return the name of this field} */ 73 | Utf8Entry fieldName(); 74 | 75 | /** {@return the field descriptor string of this field} */ 76 | Utf8Entry fieldType(); 77 | 78 | /** {@return the field type, as a symbolic descriptor} */ 79 | default ClassDesc fieldTypeSymbol() { 80 | return Util.fieldTypeSymbol(fieldType()); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/Instruction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile; 27 | 28 | import io.github.dmlloyd.classfile.attribute.CodeAttribute; 29 | import io.github.dmlloyd.classfile.instruction.*; 30 | 31 | import io.github.dmlloyd.classfile.impl.AbstractInstruction; 32 | 33 | /** 34 | * Models an executable instruction in the {@code code} array of the {@link 35 | * CodeAttribute Code} attribute of a method. The order of instructions in 36 | * a {@link CodeModel} is significant. 37 | *

38 | * The {@link #opcode() opcode} identifies the operation of an instruction. 39 | * Each {@linkplain Opcode#kind() kind} of opcode has its own modeling interface 40 | * for instructions. 41 | * 42 | * @see Opcode 43 | * @jvms 6.5 Instructions 44 | * @sealedGraph 45 | * @since 24 46 | */ 47 | public sealed interface Instruction extends CodeElement 48 | permits ArrayLoadInstruction, ArrayStoreInstruction, BranchInstruction, 49 | ConstantInstruction, ConvertInstruction, DiscontinuedInstruction, 50 | FieldInstruction, InvokeDynamicInstruction, InvokeInstruction, 51 | LoadInstruction, StoreInstruction, IncrementInstruction, 52 | LookupSwitchInstruction, MonitorInstruction, NewMultiArrayInstruction, 53 | NewObjectInstruction, NewPrimitiveArrayInstruction, NewReferenceArrayInstruction, 54 | NopInstruction, OperatorInstruction, ReturnInstruction, 55 | StackInstruction, TableSwitchInstruction, 56 | ThrowInstruction, TypeCheckInstruction, AbstractInstruction { 57 | 58 | /** 59 | * {@return the operation of this instruction} 60 | */ 61 | Opcode opcode(); 62 | 63 | /** 64 | * {@return the size in bytes of this instruction} 65 | * This value is equal to {@link Opcode#sizeIfFixed() 66 | * opcode().sizeIfFixed()} if it is not {@code -1}. 67 | */ 68 | int sizeInBytes(); 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/MethodElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile; 26 | 27 | import io.github.dmlloyd.classfile.attribute.*; 28 | 29 | /** 30 | * Marker interface for a member element of a {@link MethodModel}. Such an 31 | * element can appear when traversing a {@link MethodModel} unless otherwise 32 | * specified, be supplied to a {@link MethodBuilder}, and be processed by a 33 | * {@link MethodTransform}. 34 | *

35 | * {@link AccessFlags} is the only member element of a method that appear 36 | * exactly once during the traversal of a {@link MethodModel}. 37 | * 38 | * @see ClassFileElement##membership Membership Elements 39 | * @see ClassElement 40 | * @see FieldElement 41 | * @see CodeElement 42 | * @sealedGraph 43 | * @since 24 44 | */ 45 | public sealed interface MethodElement 46 | extends ClassFileElement 47 | permits AccessFlags, CodeModel, CustomAttribute, 48 | AnnotationDefaultAttribute, DeprecatedAttribute, 49 | ExceptionsAttribute, MethodParametersAttribute, 50 | RuntimeInvisibleAnnotationsAttribute, RuntimeInvisibleParameterAnnotationsAttribute, 51 | RuntimeInvisibleTypeAnnotationsAttribute, RuntimeVisibleAnnotationsAttribute, 52 | RuntimeVisibleParameterAnnotationsAttribute, RuntimeVisibleTypeAnnotationsAttribute, 53 | SignatureAttribute, SyntheticAttribute, UnknownAttribute { 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/PseudoInstruction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile; 26 | 27 | import io.github.dmlloyd.classfile.attribute.CodeAttribute; 28 | import io.github.dmlloyd.classfile.instruction.CharacterRange; 29 | import io.github.dmlloyd.classfile.instruction.ExceptionCatch; 30 | import io.github.dmlloyd.classfile.instruction.LabelTarget; 31 | import io.github.dmlloyd.classfile.instruction.LineNumber; 32 | import io.github.dmlloyd.classfile.instruction.LocalVariable; 33 | import io.github.dmlloyd.classfile.instruction.LocalVariableType; 34 | 35 | import io.github.dmlloyd.classfile.impl.AbstractPseudoInstruction; 36 | 37 | /** 38 | * Models metadata about a {@link CodeModel}, derived from the {@link 39 | * CodeAttribute Code} attribute itself or its attributes. 40 | *

41 | * Order is significant for some pseudo-instructions relative to {@link 42 | * Instruction}s, such as {@link LabelTarget} or {@link LineNumber}. Some 43 | * pseudo-instructions can be omitted in reading and writing according to 44 | * certain {@link ClassFile.Option}s. These are specified in the corresponding 45 | * modeling interfaces. 46 | * 47 | * @sealedGraph 48 | * @since 24 49 | */ 50 | public sealed interface PseudoInstruction 51 | extends CodeElement 52 | permits CharacterRange, ExceptionCatch, LabelTarget, LineNumber, LocalVariable, LocalVariableType, AbstractPseudoInstruction { 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/Superclass.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile; 26 | 27 | import io.github.dmlloyd.classfile.constantpool.ClassEntry; 28 | import java.lang.constant.ClassDesc; 29 | 30 | import io.github.dmlloyd.classfile.impl.SuperclassImpl; 31 | 32 | /** 33 | * Models the superclass (JVMS {@jvms 4.1}) of a class. A {@code Superclass} 34 | * appears at most once in a {@link ClassModel}: it must be absent for 35 | * {@linkplain ClassModel#isModuleInfo() module descriptors} or the {@link 36 | * Object} class, and must be present otherwise. A {@link ClassBuilder} sets 37 | * the {@link Object} class as the superclass if the superclass is not supplied 38 | * and the class to build is required to have a superclass. 39 | *

40 | * All {@linkplain ClassFile#ACC_INTERFACE interfaces} have {@link Object} as 41 | * their superclass. 42 | * 43 | * @see ClassModel#superclass() 44 | * @see ClassBuilder#withSuperclass 45 | * @jvms 4.1 The {@code ClassFile} Structure 46 | * @since 24 47 | */ 48 | public sealed interface Superclass 49 | extends ClassElement 50 | permits SuperclassImpl { 51 | 52 | /** {@return the superclass} */ 53 | ClassEntry superclassEntry(); 54 | 55 | /** 56 | * {@return a {@linkplain Superclass} element} 57 | * 58 | * @param superclassEntry the superclass 59 | */ 60 | static Superclass of(ClassEntry superclassEntry) { 61 | return new SuperclassImpl(superclassEntry); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/attribute/DeprecatedAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.attribute; 26 | 27 | import io.github.dmlloyd.classfile.*; 28 | import io.github.dmlloyd.classfile.AttributeMapper.AttributeStability; 29 | 30 | import io.github.dmlloyd.classfile.impl.BoundAttribute; 31 | import io.github.dmlloyd.classfile.impl.UnboundAttribute; 32 | 33 | /** 34 | * Models the {@link Attributes#deprecated() Deprecated} attribute (JVMS {@jvms 35 | * 4.7.15}), which indicates this structure has been superseded. 36 | *

37 | * This attribute can appear on classes, methods, and fields, and permits 38 | * {@linkplain AttributeMapper#allowMultiple multiple instances} in a structure. 39 | * It has {@linkplain AttributeStability#STATELESS no data dependency}. 40 | *

41 | * This attribute was introduced in the Java SE Platform version 1.1, major 42 | * version {@value ClassFile#JAVA_1_VERSION}. 43 | * 44 | * @apiNote 45 | * When this attribute is present, the {@link Deprecated} annotation should 46 | * also be present in the {@link RuntimeVisibleAnnotationsAttribute 47 | * RuntimeVisibleAnnotations} attribute to provide more obvious alerts. 48 | * The reference implementation of the system Java compiler emits this attribute 49 | * without the annotation when a {@code @deprecated} tag is present in the 50 | * documentation comments without the annotation. 51 | * 52 | * @see Attributes#deprecated() 53 | * @see Deprecated 54 | * @jvms 4.7.15 The {@code Deprecated} Attribute 55 | * @since 24 56 | */ 57 | public sealed interface DeprecatedAttribute 58 | extends Attribute, 59 | ClassElement, MethodElement, FieldElement 60 | permits BoundAttribute.BoundDeprecatedAttribute, 61 | UnboundAttribute.UnboundDeprecatedAttribute { 62 | 63 | /** 64 | * {@return a {@code Deprecated} attribute} 65 | */ 66 | static DeprecatedAttribute of() { 67 | return new UnboundAttribute.UnboundDeprecatedAttribute(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/attribute/LineNumberInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.attribute; 26 | 27 | import io.github.dmlloyd.classfile.CodeBuilder; 28 | import io.github.dmlloyd.classfile.instruction.LineNumber; 29 | 30 | import io.github.dmlloyd.classfile.impl.UnboundAttribute; 31 | 32 | /** 33 | * Models a single line number entry in the {@link LineNumberTableAttribute}. 34 | * 35 | * @see LineNumberTableAttribute#lineNumbers() 36 | * @see LineNumber 37 | * @since 24 38 | */ 39 | public sealed interface LineNumberInfo 40 | permits UnboundAttribute.UnboundLineNumberInfo { 41 | 42 | /** 43 | * {@return the index into the code array at which the code for this line 44 | * begins} 45 | */ 46 | int startPc(); 47 | 48 | /** 49 | * {@return the line number within the original source file} 50 | */ 51 | int lineNumber(); 52 | 53 | /** 54 | * {@return a line number description} 55 | * 56 | * @apiNote 57 | * The created entry cannot be written to a {@link CodeBuilder}. Call 58 | * {@link CodeBuilder#lineNumber CodeBuilder::lineNumber} in the correct 59 | * order instead. 60 | * 61 | * @param startPc the starting index of the code array for this line 62 | * @param lineNumber the line number within the original source file 63 | */ 64 | public static LineNumberInfo of(int startPc, int lineNumber) { 65 | return new UnboundAttribute.UnboundLineNumberInfo(startPc, lineNumber); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/attribute/LocalVariableInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.attribute; 26 | 27 | import io.github.dmlloyd.classfile.constantpool.Utf8Entry; 28 | import io.github.dmlloyd.classfile.instruction.LocalVariable; 29 | import java.lang.constant.ClassDesc; 30 | 31 | import io.github.dmlloyd.classfile.impl.BoundLocalVariable; 32 | import io.github.dmlloyd.classfile.impl.UnboundAttribute; 33 | import io.github.dmlloyd.classfile.impl.Util; 34 | 35 | /** 36 | * Models a single local variable in the {@link LocalVariableTableAttribute}. 37 | * 38 | * @see LocalVariableTableAttribute#localVariables() 39 | * @see LocalVariable 40 | * @jvms 4.7.13 The {@code LocalVaribleTable} Attribute 41 | * @since 24 42 | */ 43 | public sealed interface LocalVariableInfo 44 | permits UnboundAttribute.UnboundLocalVariableInfo, BoundLocalVariable { 45 | 46 | /** 47 | * {@return the index into the code array, inclusive, at which the scope of 48 | * this variable begins} 49 | */ 50 | int startPc(); 51 | 52 | /** 53 | * {@return the length of the region of the code array in which this 54 | * variable is in scope} 55 | */ 56 | int length(); 57 | 58 | /** 59 | * {@return the name of the local variable} 60 | */ 61 | Utf8Entry name(); 62 | 63 | /** 64 | * {@return the field descriptor string of the local variable} 65 | */ 66 | Utf8Entry type(); 67 | 68 | /** 69 | * {@return the field descriptor of the local variable} 70 | */ 71 | default ClassDesc typeSymbol() { 72 | return Util.fieldTypeSymbol(type()); 73 | } 74 | 75 | /** 76 | * {@return the index into the local variable array of the current frame 77 | * which holds this local variable} 78 | */ 79 | int slot(); 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/attribute/LocalVariableTypeInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.attribute; 26 | 27 | import io.github.dmlloyd.classfile.constantpool.Utf8Entry; 28 | import io.github.dmlloyd.classfile.instruction.LocalVariableType; 29 | 30 | import io.github.dmlloyd.classfile.impl.BoundLocalVariableType; 31 | import io.github.dmlloyd.classfile.impl.UnboundAttribute; 32 | 33 | /** 34 | * Models a single local variable in the {@link LocalVariableTypeTableAttribute}. 35 | * 36 | * @see LocalVariableTypeTableAttribute#localVariableTypes() 37 | * @see LocalVariableType 38 | * @jvms 4.7.14 The {@code LocalVariableTypeTable} Attribute 39 | * @since 24 40 | */ 41 | public sealed interface LocalVariableTypeInfo 42 | permits UnboundAttribute.UnboundLocalVariableTypeInfo, BoundLocalVariableType { 43 | 44 | /** 45 | * {@return the index into the code array, inclusive at which the scope of 46 | * this variable begins} 47 | */ 48 | int startPc(); 49 | 50 | /** 51 | * {@return the length of the region of the code array in which this 52 | * variable is in scope} 53 | */ 54 | int length(); 55 | 56 | /** 57 | * {@return the name of the local variable} 58 | */ 59 | Utf8Entry name(); 60 | 61 | 62 | /** 63 | * {@return the field signature string of the local variable} 64 | */ 65 | Utf8Entry signature(); 66 | 67 | /** 68 | * {@return the index into the local variable array of the current frame 69 | * which holds this local variable} 70 | */ 71 | int slot(); 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/attribute/ModuleHashInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.attribute; 26 | 27 | import io.github.dmlloyd.classfile.constantpool.ModuleEntry; 28 | import io.github.dmlloyd.classfile.extras.constant.ModuleDesc; 29 | 30 | import io.github.dmlloyd.classfile.impl.TemporaryConstantPool; 31 | import io.github.dmlloyd.classfile.impl.UnboundAttribute; 32 | 33 | /** 34 | * Models hash information for a single module in the {@link ModuleHashesAttribute}. 35 | * 36 | * @see ModuleHashesAttribute#hashes() 37 | * @since 24 38 | */ 39 | public sealed interface ModuleHashInfo 40 | permits UnboundAttribute.UnboundModuleHashInfo { 41 | 42 | /** 43 | * {@return the name of the related module} 44 | */ 45 | ModuleEntry moduleName(); 46 | 47 | /** 48 | * {@return the hash of the related module} 49 | */ 50 | byte[] hash(); 51 | 52 | /** 53 | * {@return a module hash description} 54 | * @param moduleName the module name 55 | * @param hash the hash value 56 | */ 57 | static ModuleHashInfo of(ModuleEntry moduleName, byte[] hash) { 58 | return new UnboundAttribute.UnboundModuleHashInfo(moduleName, hash); 59 | } 60 | 61 | /** 62 | * {@return a module hash description} 63 | * @param moduleDesc the module name 64 | * @param hash the hash value 65 | */ 66 | static ModuleHashInfo of(ModuleDesc moduleDesc, byte[] hash) { 67 | return new UnboundAttribute.UnboundModuleHashInfo(TemporaryConstantPool.INSTANCE.moduleEntry(TemporaryConstantPool.INSTANCE.utf8Entry(moduleDesc.name())), hash); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/attribute/RecordAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile.attribute; 27 | 28 | import io.github.dmlloyd.classfile.Attribute; 29 | import io.github.dmlloyd.classfile.AttributeMapper; 30 | import io.github.dmlloyd.classfile.AttributeMapper.AttributeStability; 31 | import io.github.dmlloyd.classfile.Attributes; 32 | import io.github.dmlloyd.classfile.ClassElement; 33 | import io.github.dmlloyd.classfile.ClassFile; 34 | import java.util.List; 35 | 36 | import io.github.dmlloyd.classfile.impl.BoundAttribute; 37 | import io.github.dmlloyd.classfile.impl.UnboundAttribute; 38 | 39 | /** 40 | * Models the {@link Attributes#record() Record} attribute (JVMS {@jvms 4.7.30}), 41 | * which indicates that this class is a record class and the record 42 | * components. 43 | *

44 | * This attribute only appears on classes, and does not permit {@linkplain 45 | * AttributeMapper#allowMultiple multiple instances} in a class. It has a 46 | * data dependency on the {@linkplain AttributeStability#CP_REFS constant pool}. 47 | *

48 | * The attribute was introduced in the Java SE Platform version 16, major 49 | * version {@value ClassFile#JAVA_16_VERSION}. 50 | * 51 | * @see Attributes#record() 52 | * @see Class#isRecord() 53 | * @see Class#getRecordComponents() 54 | * @jvms 4.7.30 The {@code Record} Attribute 55 | * @since 24 56 | */ 57 | public sealed interface RecordAttribute extends Attribute, ClassElement 58 | permits BoundAttribute.BoundRecordAttribute, UnboundAttribute.UnboundRecordAttribute { 59 | 60 | /** 61 | * {@return the components of this record class} 62 | * 63 | * @see Class#getRecordComponents() 64 | */ 65 | List components(); 66 | 67 | /** 68 | * {@return a {@code Record} attribute} 69 | * 70 | * @param components the record components 71 | */ 72 | static RecordAttribute of(List components) { 73 | return new UnboundAttribute.UnboundRecordAttribute(components); 74 | } 75 | 76 | /** 77 | * {@return a {@code Record} attribute} 78 | * 79 | * @param components the record components 80 | */ 81 | static RecordAttribute of(RecordComponentInfo... components) { 82 | return of(List.of(components)); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/attribute/SourceDebugExtensionAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile.attribute; 27 | 28 | import java.io.DataInput; 29 | import io.github.dmlloyd.classfile.Attribute; 30 | import io.github.dmlloyd.classfile.AttributeMapper; 31 | import io.github.dmlloyd.classfile.AttributeMapper.AttributeStability; 32 | import io.github.dmlloyd.classfile.Attributes; 33 | import io.github.dmlloyd.classfile.ClassElement; 34 | import io.github.dmlloyd.classfile.ClassFile; 35 | 36 | import io.github.dmlloyd.classfile.impl.BoundAttribute; 37 | import io.github.dmlloyd.classfile.impl.UnboundAttribute; 38 | 39 | /** 40 | * Models the {@link Attributes#sourceDebugExtension() SourceDebugExtension} 41 | * attribute (JVMS {@jvms 4.7.11}), which stores arbitrary {@linkplain 42 | * DataInput##modified-utf-8 modified UTF-8} data. 43 | *

44 | * This attribute only appears on classes, and does not permit {@linkplain 45 | * AttributeMapper#allowMultiple multiple instances} in a class. It has 46 | * {@linkplain AttributeStability#STATELESS no data dependency}. 47 | *

48 | * The attribute was introduced in the Java SE Platform version 5.0, major 49 | * version {@value ClassFile#JAVA_5_VERSION}. 50 | * 51 | * @see Attributes#sourceDebugExtension() 52 | * @jvms 4.7.11 The {@code SourceDebugExtension} Attribute 53 | * @since 24 54 | */ 55 | public sealed interface SourceDebugExtensionAttribute 56 | extends Attribute, ClassElement 57 | permits BoundAttribute.BoundSourceDebugExtensionAttribute, UnboundAttribute.UnboundSourceDebugExtensionAttribute { 58 | 59 | /** 60 | * {@return the debug extension payload} The payload may denote a string 61 | * longer than that which can be represented with a {@link String}. 62 | */ 63 | byte[] contents(); 64 | 65 | /** 66 | * {@return a {@code SourceDebugExtension} attribute} 67 | * @param contents the extension contents 68 | */ 69 | static SourceDebugExtensionAttribute of(byte[] contents) { 70 | return new UnboundAttribute.UnboundSourceDebugExtensionAttribute(contents); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/attribute/SyntheticAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile.attribute; 27 | 28 | import io.github.dmlloyd.classfile.*; 29 | import io.github.dmlloyd.classfile.AttributeMapper.AttributeStability; 30 | import io.github.dmlloyd.classfile.extras.reflect.AccessFlag; 31 | 32 | import io.github.dmlloyd.classfile.impl.BoundAttribute; 33 | import io.github.dmlloyd.classfile.impl.UnboundAttribute; 34 | 35 | /** 36 | * Models the {@link Attributes#synthetic() Synthetic} attribute (JVMS {@jvms 37 | * 4.7.8}), which marks a class member as implementation-specific artifacts. 38 | *

39 | * This attribute can appear on classes, methods, and fields, and permits 40 | * {@linkplain AttributeMapper#allowMultiple multiple instances} in a structure. 41 | * It has {@linkplain AttributeStability#STATELESS no data dependency}. 42 | *

43 | * This attribute was introduced in the Java SE Platform version 1.1, major 44 | * version {@value ClassFile#JAVA_1_VERSION}. 45 | * 46 | * @apiNote 47 | * This attribute has been largely superseded by the {@link AccessFlag#SYNTHETIC 48 | * ACC_SYNTHETIC} modifier in newer {@code class} files. See {@link 49 | * java.compiler/javax.lang.model.util.Elements.Origin} for a more in-depth 50 | * description about the differences between synthetic and implicit (mandated) 51 | * constructs generated by compilers. 52 | * 53 | * @see Attributes#synthetic() 54 | * @see AccessFlag#SYNTHETIC 55 | * @jvms 4.7.8 The {@code Synthetic} Attribute 56 | * @since 24 57 | */ 58 | @SuppressWarnings("doclint:reference") 59 | public sealed interface SyntheticAttribute 60 | extends Attribute, 61 | ClassElement, MethodElement, FieldElement 62 | permits BoundAttribute.BoundSyntheticAttribute, UnboundAttribute.UnboundSyntheticAttribute { 63 | 64 | /** 65 | * {@return a {@code Synthetic} attribute} 66 | */ 67 | static SyntheticAttribute of() { 68 | return new UnboundAttribute.UnboundSyntheticAttribute(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/attribute/UnknownAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile.attribute; 27 | 28 | import io.github.dmlloyd.classfile.*; 29 | import io.github.dmlloyd.classfile.AttributeMapper.AttributeStability; 30 | 31 | import io.github.dmlloyd.classfile.impl.BoundAttribute; 32 | 33 | /** 34 | * Models an unknown attribute read from a {@code class} file. An attribute is 35 | * unknown if it is not recognized by one of the mappers in {@link Attributes} 36 | * and is not recognized by the {@link ClassFile.AttributesProcessingOption}. 37 | *

38 | * An unknown attribute may appear anywhere where an attribute may appear, and 39 | * has an {@linkplain AttributeStability#UNKNOWN unknown} data dependency. 40 | * 41 | * @see CustomAttribute 42 | * @since 24 43 | */ 44 | public sealed interface UnknownAttribute 45 | extends Attribute, 46 | ClassElement, MethodElement, FieldElement, CodeElement 47 | permits BoundAttribute.BoundUnknownAttribute { 48 | 49 | /** 50 | * {@return the uninterpreted contents of the attribute payload} 51 | */ 52 | byte[] contents(); 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/attribute/snippet-files/PackageSnippets.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.attribute.snippet; 26 | 27 | import io.github.dmlloyd.classfile.AttributedElement; 28 | import io.github.dmlloyd.classfile.Attributes; 29 | import io.github.dmlloyd.classfile.CodeBuilder; 30 | import io.github.dmlloyd.classfile.MethodModel; 31 | import io.github.dmlloyd.classfile.attribute.RuntimeVisibleAnnotationsAttribute; 32 | import java.util.List; 33 | 34 | class PackageSnippets { 35 | 36 | // @start region=hasDeprecated 37 | private static final String DEPRECATED_DESC = Deprecated.class.descriptorString(); 38 | 39 | static boolean hasDeprecated(AttributedElement element) { 40 | var annotations = element.findAttribute(Attributes.runtimeVisibleAnnotations()) 41 | .map(RuntimeVisibleAnnotationsAttribute::annotations) 42 | .orElse(List.of()); 43 | for (var anno : annotations) { 44 | // equalsString reduces extra computations for raw UTF-8 entries 45 | if (anno.className().equalsString(DEPRECATED_DESC)) { 46 | return true; 47 | } 48 | } 49 | return false; 50 | } 51 | // @end 52 | 53 | // @start region=reuseStackMaps 54 | static void reuseStackMaps(MethodModel oldMethod, CodeBuilder cob) { 55 | var oldCode = oldMethod.code().orElseThrow(); 56 | // The StackMapTable attribute is not streamed in CodeModel, so this is 57 | // the only way to obtain it 58 | // @link substring="findAttribute" target="AttributedElement#findAttribute" : 59 | var stackMaps = oldCode.findAttribute(Attributes.stackMapTable()); 60 | stackMaps.ifPresent(cob); // Note: CodeBuilder is a Consumer 61 | } 62 | // @end 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/components/CodeLocalsShifter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.components; 26 | 27 | import io.github.dmlloyd.classfile.AccessFlags; 28 | import io.github.dmlloyd.classfile.CodeTransform; 29 | import io.github.dmlloyd.classfile.TypeKind; 30 | import java.lang.constant.MethodTypeDesc; 31 | import io.github.dmlloyd.classfile.extras.reflect.AccessFlag; 32 | 33 | import io.github.dmlloyd.classfile.impl.CodeLocalsShifterImpl; 34 | 35 | /** 36 | * {@link CodeLocalsShifter} is a {@link CodeTransform} shifting locals to 37 | * newly allocated positions to avoid conflicts during code injection. 38 | * Locals pointing to the receiver or to method arguments slots are never shifted. 39 | * All locals pointing beyond the method arguments are re-indexed in order of appearance. 40 | */ 41 | public sealed interface CodeLocalsShifter extends CodeTransform permits CodeLocalsShifterImpl { 42 | 43 | /** 44 | * Creates a new instance of {@link CodeLocalsShifter} 45 | * with fixed local slots calculated from provided method information. 46 | * @param methodFlags flags of the method to construct {@link CodeLocalsShifter} for 47 | * @param methodDescriptor descriptor of the method to construct {@link CodeLocalsShifter} for 48 | * @return new instance of {@link CodeLocalsShifter} 49 | */ 50 | static CodeLocalsShifter of(AccessFlags methodFlags, MethodTypeDesc methodDescriptor) { 51 | int fixed = methodFlags.has(AccessFlag.STATIC) ? 0 : 1; 52 | for (var param : methodDescriptor.parameterList()) 53 | fixed += TypeKind.from(param).slotSize(); 54 | return new CodeLocalsShifterImpl(fixed); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/AnnotationConstantValueEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import io.github.dmlloyd.classfile.AnnotationValue; 28 | import java.lang.constant.ConstantDesc; 29 | 30 | /** 31 | * Marker interface for constant pool entries that can represent constant values 32 | * associated with elements of annotations. They are also the only entries that 33 | * do not refer to other constant pool entries. 34 | * 35 | * @apiNote 36 | * An annotation constant value entry alone is not sufficient to determine 37 | * the annotation constant; for example, an {@link IntegerEntry} of {@code 1} 38 | * can mean {@code true} in {@link AnnotationValue.OfBoolean} or {@code 1} 39 | * in {@link AnnotationValue.OfInt}. 40 | * 41 | * @see AnnotationValue.OfConstant 42 | * @jvms 4.7.16.1 The {@code element_value} structure 43 | * @sealedGraph 44 | * @since 24 45 | */ 46 | public sealed interface AnnotationConstantValueEntry extends PoolEntry 47 | permits DoubleEntry, FloatEntry, IntegerEntry, LongEntry, Utf8Entry { 48 | 49 | /** 50 | * {@return the constant value} The constant value will be an {@link 51 | * Integer}, {@link Long}, {@link Float}, {@link Double} for the primitive 52 | * constants, or {@link String} for UTF8 constants. 53 | */ 54 | ConstantDesc constantValue(); 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/ConstantPoolException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | 28 | /** 29 | * Thrown to indicate that requested entry cannot be obtained from the constant 30 | * pool or the bootstrap method table. This is also thrown when the lazy 31 | * evaluation of constant pool or bootstrap method table entries encounter 32 | * format errors. 33 | * 34 | * @since 24 35 | */ 36 | public class ConstantPoolException extends IllegalArgumentException { 37 | 38 | @java.io.Serial 39 | private static final long serialVersionUID = 7245472922409094120L; 40 | 41 | /** 42 | * Constructs a {@code ConstantPoolException} with no detail message. 43 | */ 44 | public ConstantPoolException() { 45 | super(); 46 | } 47 | 48 | /** 49 | * Constructs a {@code ConstantPoolException} with the specified detail 50 | * message. 51 | * 52 | * @param message the detail message, may be {@code null} for no detail 53 | * message 54 | */ 55 | public ConstantPoolException(String message) { 56 | super(message); 57 | } 58 | 59 | /** 60 | * Constructs a {@code ConstantPoolException} with the specified cause and 61 | * a detail message of {@code cause == null ? null : cause.toString()}. 62 | * 63 | * @param cause the cause, may be {@code null} for nonexistent or unknown 64 | * cause 65 | */ 66 | public ConstantPoolException(Throwable cause) { 67 | super(cause); 68 | } 69 | 70 | /** 71 | * Constructs a {@code ConstantPoolException} with the specified detail 72 | * message and cause. 73 | * 74 | * @param message the detail message, may be {@code null} for no detail 75 | * message 76 | * @param cause the cause, may be {@code null} for nonexistent or unknown 77 | * cause 78 | */ 79 | public ConstantPoolException(String message, Throwable cause) { 80 | super(message, cause); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/ConstantValueEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import io.github.dmlloyd.classfile.Attributes; 28 | import java.lang.constant.ConstantDesc; 29 | 30 | /** 31 | * Marker interface for constant pool entries that can represent constant values 32 | * in the {@link Attributes#constantValue() ConstantValue} attribute. 33 | * 34 | * @see ConstantPoolBuilder#constantValueEntry 35 | * ConstantPoolBuilder::constantValueEntry 36 | * @sealedGraph 37 | * @since 24 38 | */ 39 | public sealed interface ConstantValueEntry extends LoadableConstantEntry 40 | permits DoubleEntry, FloatEntry, IntegerEntry, LongEntry, StringEntry { 41 | 42 | /** 43 | * {@return the constant value} The constant value will be an {@link 44 | * Integer}, {@link Long}, {@link Float}, {@link Double}, or {@link String}. 45 | * 46 | * @see ConstantPoolBuilder#constantValueEntry(ConstantDesc) 47 | */ 48 | @Override 49 | ConstantDesc constantValue(); 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/DoubleEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import io.github.dmlloyd.classfile.TypeKind; 28 | 29 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 30 | 31 | /** 32 | * Models a {@code CONSTANT_Double_info} structure, representing a {@code 33 | * double} constant, in the constant pool of a {@code class} file. 34 | *

35 | * The use of a {@code DoubleEntry} is modeled by a {@code double}. Conversions 36 | * are through {@link ConstantPoolBuilder#doubleEntry} and {@link #doubleValue()}. 37 | * In the conversions, all NaN values of the {@code double} may or may not be 38 | * collapsed into a single {@linkplain Double#NaN "canonical" NaN value}. 39 | *

40 | * A double entry has a {@linkplain #width() width} of {@code 2}, making its 41 | * subsequent constant pool index valid and unusable. 42 | * 43 | * @see ConstantPoolBuilder#doubleEntry ConstantPoolBuilder::doubleEntry 44 | * @jvms 4.4.5 The {@code CONSTANT_Long_info} and {@code CONSTANT_Double_info} 45 | * Structures 46 | * @since 24 47 | */ 48 | public sealed interface DoubleEntry 49 | extends AnnotationConstantValueEntry, ConstantValueEntry 50 | permits AbstractPoolEntry.DoubleEntryImpl { 51 | 52 | /** 53 | * {@return the {@code double} value} 54 | * 55 | * @see ConstantPoolBuilder#doubleEntry(double) 56 | * ConstantPoolBuilder::doubleEntry(double) 57 | */ 58 | double doubleValue(); 59 | 60 | @Override 61 | default TypeKind typeKind() { 62 | return TypeKind.DOUBLE; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/FieldRefEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import java.lang.constant.ClassDesc; 28 | 29 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 30 | import io.github.dmlloyd.classfile.impl.Util; 31 | 32 | /** 33 | * Models a {@code CONSTANT_Fieldref_info} structure, or a symbolic reference 34 | * to a field, in the constant pool of a {@code class} file. 35 | *

36 | * A field reference constant pool entry is composite: 37 | * {@snippet lang=text : 38 | * // @link substring="FieldRefEntry" target="ConstantPoolBuilder#fieldRefEntry(ClassEntry, NameAndTypeEntry)" : 39 | * FieldRefEntry( 40 | * ClassEntry owner, // @link substring="owner" target="#owner()" 41 | * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" 42 | * ) 43 | * } 44 | * where the {@link #type() nameAndType.type()} represents a {@linkplain 45 | * #typeSymbol() field descriptor} string. 46 | * 47 | * @see ConstantPoolBuilder#fieldRefEntry ConstantPoolBuilder::fieldRefEntry 48 | * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code 49 | * CONSTANT_Methodref_info}, and {@code 50 | * CONSTANT_InterfaceMethodref_info} Structures 51 | * @since 24 52 | */ 53 | public sealed interface FieldRefEntry extends MemberRefEntry 54 | permits AbstractPoolEntry.FieldRefEntryImpl { 55 | 56 | /** 57 | * {@return a symbolic descriptor for the {@linkplain #type() field type}} 58 | */ 59 | default ClassDesc typeSymbol() { 60 | return Util.fieldTypeSymbol(type()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/FloatEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import io.github.dmlloyd.classfile.TypeKind; 28 | 29 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 30 | 31 | /** 32 | * Models a {@code CONSTANT_Float_info} structure, or a {@code float} constant, 33 | * in the constant pool of a {@code class} file. 34 | *

35 | * The use of a {@code FloatEntry} is modeled by a {@code float}. Conversions 36 | * are through {@link ConstantPoolBuilder#floatEntry} and {@link #floatValue()}. 37 | * In the conversions, all NaN values of the {@code float} may or may not be 38 | * collapsed into a single {@linkplain Float#NaN "canonical" NaN value}. 39 | * 40 | * @see ConstantPoolBuilder#floatEntry ConstantPoolBuilder::floatEntry 41 | * @jvms 4.4.4 The {@code CONSTANT_Integer_info} and {@code CONSTANT_Float_info} 42 | * Structures 43 | * @since 24 44 | */ 45 | public sealed interface FloatEntry 46 | extends AnnotationConstantValueEntry, ConstantValueEntry 47 | permits AbstractPoolEntry.FloatEntryImpl { 48 | 49 | /** 50 | * {@return the {@code float} value} 51 | * 52 | * @see ConstantPoolBuilder#floatEntry(float) 53 | */ 54 | float floatValue(); 55 | 56 | @Override 57 | default TypeKind typeKind() { 58 | return TypeKind.FLOAT; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/IntegerEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import io.github.dmlloyd.classfile.TypeKind; 28 | 29 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 30 | 31 | /** 32 | * Models a {@code CONSTANT_Integer_info} structure, or an {@code int} constant, 33 | * in the constant pool of a {@code class} file. 34 | *

35 | * The use of a {@code IntegerEntry} is modeled by an {@code int}. Conversions 36 | * are through {@link ConstantPoolBuilder#intEntry(int)} and {@link #intValue()}. 37 | * 38 | * @see ConstantPoolBuilder#intEntry ConstantPoolBuilder::intEntry 39 | * @jvms 4.4.4 The {@code CONSTANT_Integer_info} and {@code CONSTANT_Float_info} 40 | * Structures 41 | * @since 24 42 | */ 43 | public sealed interface IntegerEntry 44 | extends AnnotationConstantValueEntry, ConstantValueEntry 45 | permits AbstractPoolEntry.IntegerEntryImpl { 46 | 47 | /** 48 | * {@return the {@code int} value} 49 | * 50 | * @see ConstantPoolBuilder#intEntry(int) 51 | */ 52 | int intValue(); 53 | 54 | @Override 55 | default TypeKind typeKind() { 56 | return TypeKind.INT; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/InterfaceMethodRefEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import java.lang.constant.MethodTypeDesc; 28 | 29 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 30 | import io.github.dmlloyd.classfile.impl.Util; 31 | 32 | /** 33 | * Models a {@code CONSTANT_InterfaceMethodRef_info} structure, or a symbolic 34 | * reference to an interface method, in the constant pool of a {@code class} 35 | * file. 36 | *

37 | * An interface method reference entry is composite: 38 | * {@snippet lang=text : 39 | * // @link substring="InterfaceMethodRefEntry" target="ConstantPoolBuilder#interfaceMethodRefEntry(ClassEntry, NameAndTypeEntry)" : 40 | * InterfaceMethodRefEntry( 41 | * ClassEntry owner, // @link substring="owner" target="#owner()" 42 | * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" 43 | * ) 44 | * } 45 | * where the {@link #type() type} in the {@code nameAndType} is a {@linkplain 46 | * #typeSymbol() method descriptor} string. 47 | * 48 | * @see ConstantPoolBuilder#interfaceMethodRefEntry 49 | * ConstantPoolBuilder::interfaceMethodRefEntry 50 | * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code 51 | * CONSTANT_Methodref_info}, and {@code 52 | * CONSTANT_InterfaceMethodref_info} Structures 53 | * @since 24 54 | */ 55 | public sealed interface InterfaceMethodRefEntry 56 | extends MemberRefEntry 57 | permits AbstractPoolEntry.InterfaceMethodRefEntryImpl { 58 | 59 | /** 60 | * {@return a symbolic descriptor for the {@linkplain #type() method type}} 61 | */ 62 | default MethodTypeDesc typeSymbol() { 63 | return Util.methodTypeSymbol(type()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/LoadableConstantEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import io.github.dmlloyd.classfile.CodeBuilder; 28 | import io.github.dmlloyd.classfile.Opcode; 29 | import io.github.dmlloyd.classfile.TypeKind; 30 | import io.github.dmlloyd.classfile.instruction.ConstantInstruction; 31 | import java.lang.constant.ConstantDesc; 32 | 33 | /** 34 | * Marker interface for constant pool entries suitable for loading via the 35 | * {@link ConstantInstruction.LoadConstantInstruction ldc} instructions. 36 | *

37 | * The use of a {@code LoadableConstantEntry} is modeled by a {@link ConstantDesc}. 38 | * Conversions are through {@link ConstantPoolBuilder#loadableConstantEntry(ConstantDesc)} 39 | * and {@link #constantValue()}. 40 | * 41 | * @see CodeBuilder#ldc(LoadableConstantEntry) 42 | * @jvms 4.4 The Constant Pool 43 | * @sealedGraph 44 | * @since 24 45 | */ 46 | public sealed interface LoadableConstantEntry extends PoolEntry 47 | permits ClassEntry, ConstantDynamicEntry, ConstantValueEntry, MethodHandleEntry, MethodTypeEntry { 48 | 49 | /** 50 | * {@return a symbolic descriptor of this constant} 51 | * 52 | * @see ConstantPoolBuilder#loadableConstantEntry(ConstantDesc) 53 | */ 54 | ConstantDesc constantValue(); 55 | 56 | /** 57 | * {@return the data type of this constant} 58 | *

59 | * If the data type is of {@linkplain TypeKind#slotSize() category} 2, this 60 | * constant must be loaded with {@link Opcode#LDC2_W ldc2_w}; otherwise, the 61 | * data type is of category 1, and this constant must be loaded with {@link 62 | * Opcode#LDC ldc} or {@link Opcode#LDC_W ldc_w}. 63 | */ 64 | default TypeKind typeKind() { 65 | return TypeKind.REFERENCE; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/LongEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import io.github.dmlloyd.classfile.TypeKind; 28 | 29 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 30 | 31 | /** 32 | * Models a {@code CONSTANT_Long_info} structure, or a {@code long} constant, in 33 | * the constant pool of a {@code class} file. 34 | *

35 | * The use of a {@code LongEntry} is modeled by a {@code long}. Conversions are 36 | * through {@link ConstantPoolBuilder#longEntry(long)} and {@link #longValue()}. 37 | *

38 | * A long entry has a {@linkplain #width() width} of {@code 2}, making its 39 | * subsequent constant pool index valid and unusable. 40 | * 41 | * @see ConstantPoolBuilder#longEntry ConstantPoolBuilder::longEntry 42 | * @jvms 4.4.5 The {@code CONSTANT_Long_info} and {@code CONSTANT_Double_info} 43 | * Structures 44 | * @since 24 45 | */ 46 | public sealed interface LongEntry 47 | extends AnnotationConstantValueEntry, ConstantValueEntry 48 | permits AbstractPoolEntry.LongEntryImpl { 49 | 50 | /** 51 | * {@return the {@code long} value} 52 | * 53 | * @see ConstantPoolBuilder#longEntry(long) 54 | * ConstantPoolBuilder::longEntry(long) 55 | */ 56 | long longValue(); 57 | 58 | /** 59 | * {@return the type of the constant} 60 | */ 61 | @Override 62 | default TypeKind typeKind() { 63 | return TypeKind.LONG; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/MethodRefEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import java.lang.constant.MethodTypeDesc; 28 | 29 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 30 | import io.github.dmlloyd.classfile.impl.Util; 31 | 32 | /** 33 | * Models a {@code CONSTANT_MethodRef_info} structure, or a symbolic reference 34 | * to a class method, in the constant pool of a {@code class} file. 35 | *

36 | * A class method reference entry is composite: 37 | * {@snippet lang=text : 38 | * // @link substring="MethodRefEntry" target="ConstantPoolBuilder#methodRefEntry(ClassEntry, NameAndTypeEntry)" : 39 | * MethodRefEntry( 40 | * ClassEntry owner, // @link substring="owner" target="#owner()" 41 | * NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()" 42 | * ) 43 | * } 44 | * where the type in the {@code NameAndTypeEntry} is a {@linkplain #typeSymbol() 45 | * method descriptor} string. 46 | * 47 | * @see ConstantPoolBuilder#methodRefEntry ConstantPoolBuilder::methodRefEntry 48 | * @jvms 4.4.2 The {@code CONSTANT_Fieldref_info}, {@code 49 | * CONSTANT_Methodref_info}, and {@code 50 | * CONSTANT_InterfaceMethodref_info} Structures 51 | * @since 24 52 | */ 53 | public sealed interface MethodRefEntry extends MemberRefEntry 54 | permits AbstractPoolEntry.MethodRefEntryImpl { 55 | 56 | /** 57 | * {@return a symbolic descriptor for the {@linkplain #type() method type}} 58 | */ 59 | default MethodTypeDesc typeSymbol() { 60 | return Util.methodTypeSymbol(type()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/MethodTypeEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import java.lang.constant.ConstantDesc; 28 | import java.lang.constant.MethodTypeDesc; 29 | 30 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 31 | 32 | /** 33 | * Models a {@code CONSTANT_MethodType_info} structure, or a symbolic reference 34 | * to a method type, in the constant pool of a {@code class} file. 35 | *

36 | * The use of a {@code MethodTypeEntry} is modeled by a {@link MethodTypeDesc}. 37 | * Conversions are through {@link ConstantPoolBuilder#methodTypeEntry(MethodTypeDesc)} 38 | * and {@link #asSymbol()}. 39 | *

40 | * A method type entry is composite: 41 | * {@snippet lang=text : 42 | * // @link substring="MethodTypeEntry" target="ConstantPoolBuilder#methodTypeEntry(Utf8Entry)" : 43 | * MethodTypeEntry(Utf8Entry descriptor) // @link substring="descriptor" target="#descriptor()" 44 | * } 45 | * where {@code descriptor} is a {@linkplain #asSymbol() method descriptor} 46 | * string. 47 | * 48 | * @jvms 4.4.9 The {@code CONSTANT_MethodType_info} Structure 49 | * @since 24 50 | */ 51 | public sealed interface MethodTypeEntry 52 | extends LoadableConstantEntry 53 | permits AbstractPoolEntry.MethodTypeEntryImpl { 54 | 55 | /** 56 | * {@inheritDoc} 57 | *

58 | * This is equivalent to {@link #asSymbol() asSymbol()}. 59 | */ 60 | @Override 61 | default ConstantDesc constantValue() { 62 | return asSymbol(); 63 | } 64 | 65 | /** 66 | * {@return the {@linkplain #asSymbol() method descriptor} string} 67 | */ 68 | Utf8Entry descriptor(); 69 | 70 | /** 71 | * {@return a symbolic descriptor for the {@linkplain #descriptor() method 72 | * type}} 73 | * 74 | * @apiNote 75 | * If only symbol equivalence is desired, {@link #matches(MethodTypeDesc) 76 | * matches} should be used. It requires reduced parsing and can 77 | * improve {@code class} file reading performance. 78 | */ 79 | MethodTypeDesc asSymbol(); 80 | 81 | /** 82 | * {@return whether this entry describes the given method type} 83 | * 84 | * @param desc the method type descriptor 85 | * @since 25 86 | */ 87 | boolean matches(MethodTypeDesc desc); 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/ModuleEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import io.github.dmlloyd.classfile.extras.constant.ModuleDesc; 28 | 29 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 30 | 31 | /** 32 | * Models a {@code CONSTANT_Module_info} structure, denoting a module, in the 33 | * constant pool of a {@code class} file. 34 | *

35 | * The use of a {@code ModuleEntry} is modeled by a {@link ModuleDesc}. 36 | * Conversions are through {@link ConstantPoolBuilder#moduleEntry(ModuleDesc)} 37 | * and {@link #asSymbol()}. 38 | *

39 | * A module entry is composite: 40 | * {@snippet lang=text : 41 | * // @link substring="ModuleEntry" target="ConstantPoolBuilder#moduleEntry(Utf8Entry)" : 42 | * ModuleEntry(Utf8Entry name) // @link substring="name" target="#name()" 43 | * } 44 | * where {@code name} is a {@linkplain #asSymbol() module name}. 45 | * 46 | * @jvms 4.4.11 The {@code CONSTANT_Module_info} Structure 47 | * @since 24 48 | */ 49 | public sealed interface ModuleEntry extends PoolEntry 50 | permits AbstractPoolEntry.ModuleEntryImpl { 51 | /** 52 | * {@return the name of the {@linkplain #asSymbol() module}} 53 | */ 54 | Utf8Entry name(); 55 | 56 | /** 57 | * {@return a symbolic descriptor for the {@linkplain #name() module name}} 58 | * 59 | * @apiNote 60 | * If only symbol equivalence is desired, {@link #matches(ModuleDesc) 61 | * matches} should be used. It requires reduced parsing and can 62 | * improve {@code class} file reading performance. 63 | */ 64 | ModuleDesc asSymbol(); 65 | 66 | /** 67 | * {@return whether this entry describes the given module} 68 | * 69 | * @param desc the module descriptor 70 | * @since 25 71 | */ 72 | boolean matches(ModuleDesc desc); 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/NameAndTypeEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import java.lang.constant.ClassDesc; 28 | import java.lang.constant.MethodTypeDesc; 29 | import java.lang.invoke.TypeDescriptor; 30 | 31 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 32 | 33 | /** 34 | * Models a {@code CONSTANT_NameAndType_info} structure, representing a field or 35 | * method, in the constant pool of a {@code class} file. 36 | *

37 | * The use of a {@code NameAndTypeEntry} is symbolically represented as a 38 | * {@code String name}, and a {@link ConstantPoolBuilder#nameAndTypeEntry(String, 39 | * ClassDesc) ClassDesc} or a {@link ConstantPoolBuilder#nameAndTypeEntry(String, 40 | * MethodTypeDesc) MethodTypeDesc} {@code type}, depending on where this {@code 41 | * NameAndTypeEntry} appears. The accessors to the symbolic descriptors for the 42 | * {@code type} is defined on a per-use-site basis, such as {@link 43 | * FieldRefEntry#typeSymbol()} returning a {@code ClassDesc}, and {@link 44 | * MethodRefEntry#typeSymbol()} returning a {@code MethodTypeDesc}. 45 | *

46 | * A name and type entry is composite: 47 | * {@snippet lang=text : 48 | * NameAndTypeEntry( // @link substring="NameAndTypeEntry" target="ConstantPoolBuilder#nameAndTypeEntry(Utf8Entry, Utf8Entry)" 49 | * Utf8Entry name, // @link substring="name" target="#name()" 50 | * Utf8Entry type // @link substring="type" target="#type()" 51 | * ) 52 | * } 53 | * where {@code name} is an unqualified name, and {@code type} is a field or 54 | * method descriptor string. 55 | * 56 | * @jvms 4.4.6 The {@code CONSTANT_NameAndType_info} Structure 57 | * @since 24 58 | */ 59 | public sealed interface NameAndTypeEntry extends PoolEntry 60 | permits AbstractPoolEntry.NameAndTypeEntryImpl { 61 | 62 | /** 63 | * {@return the field or method name} 64 | */ 65 | Utf8Entry name(); 66 | 67 | /** 68 | * {@return the field or method {@linkplain TypeDescriptor descriptor} 69 | * string} It is a method descriptor strings if it starts with {@code (}. 70 | * Otherwise, it is a field descriptor string, and must start with one of 71 | * the {@code BCDFIJSZL[} characters. 72 | */ 73 | Utf8Entry type(); 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/PackageEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import io.github.dmlloyd.classfile.extras.constant.PackageDesc; 28 | 29 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 30 | 31 | /** 32 | * Models a {@code CONSTANT_Package_info}, representing a package, in the 33 | * constant pool of a {@code class} file. 34 | *

35 | * The use of a {@code PackageEntry} is represented by a {@link PackageDesc} 36 | * that does not represent the unnamed package. Conversions are through 37 | * {@link ConstantPoolBuilder#packageEntry(PackageDesc)} and 38 | * {@link #asSymbol()}. 39 | *

40 | * A package entry is composite: 41 | * {@snippet lang=text : 42 | * // @link substring="PackageEntry" target="ConstantPoolBuilder#packageEntry(Utf8Entry)" : 43 | * PackageEntry(Utf8Entry name) // @link substring="name" target="#name()" 44 | * } 45 | * where {@code name} is the {@linkplain ClassEntry##internalname internal form} 46 | * of a binary package name and is not empty. 47 | * 48 | * @jvms 4.4.12 The {@code CONSTANT_Package_info} Structure 49 | * @since 24 50 | */ 51 | public sealed interface PackageEntry extends PoolEntry 52 | permits AbstractPoolEntry.PackageEntryImpl { 53 | /** 54 | * {@return the {@linkplain ClassEntry##internalname internal form} of the 55 | * {@linkplain #asSymbol() package} name} 56 | */ 57 | Utf8Entry name(); 58 | 59 | /** 60 | * {@return a symbolic descriptor for the {@linkplain #name() package name}} 61 | * 62 | * @apiNote 63 | * If only symbol equivalence is desired, {@link #matches(PackageDesc) 64 | * matches} should be used. It requires reduced parsing and can 65 | * improve {@code class} file reading performance. 66 | */ 67 | PackageDesc asSymbol(); 68 | 69 | /** 70 | * {@return whether this entry describes the given package} 71 | * 72 | * @param desc the package descriptor 73 | * @since 25 74 | */ 75 | boolean matches(PackageDesc desc); 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/StringEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool; 26 | 27 | import io.github.dmlloyd.classfile.impl.AbstractPoolEntry; 28 | 29 | /** 30 | * Models a {@code CONSTANT_String_info} structure, or a string constant, in the 31 | * constant pool of a {@code class} file. 32 | *

33 | * The use of a {@code StringEntry} is represented by a {@link String}. 34 | * Conversions are through {@link ConstantPoolBuilder#stringEntry(String)} and 35 | * {@link #stringValue()}. 36 | *

37 | * A string entry is composite: 38 | * {@snippet lang=text : 39 | * // @link substring="StringEntry" target="ConstantPoolBuilder#stringEntry(Utf8Entry)" : 40 | * StringEntry(Utf8Entry utf8) // @link substring="utf8" target="#utf8()" 41 | * } 42 | * 43 | * @jvms 4.4.3 The {@code CONSTANT_String_info} Structure 44 | * @since 24 45 | */ 46 | public sealed interface StringEntry 47 | extends ConstantValueEntry 48 | permits AbstractPoolEntry.StringEntryImpl { 49 | /** 50 | * {@return the UTF constant pool entry describing the string contents} 51 | * 52 | * @see ConstantPoolBuilder#stringEntry(Utf8Entry) 53 | */ 54 | Utf8Entry utf8(); 55 | 56 | /** 57 | * {@return the string value for this entry} 58 | * 59 | * @apiNote 60 | * A {@code Utf8Entry} can be used directly as a {@link CharSequence} if 61 | * {@code String} functionalities are not strictly desired. If only string 62 | * equivalence is desired, {@link #equalsString(String) equalsString} should 63 | * be used. Reduction of string processing can significantly improve {@code 64 | * class} file reading performance. 65 | * 66 | * @see ConstantPoolBuilder#stringEntry(String) 67 | */ 68 | String stringValue(); 69 | 70 | /** 71 | * {@return whether this entry describes the same string as the provided string} 72 | * 73 | * @param value the string to compare to 74 | * @since 25 75 | */ 76 | boolean equalsString(String value); 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/constantpool/snippet-files/PackageSnippets.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.constantpool.snippet; 26 | 27 | import io.github.dmlloyd.classfile.ClassFile; 28 | import io.github.dmlloyd.classfile.MethodModel; 29 | import io.github.dmlloyd.classfile.constantpool.Utf8Entry; 30 | 31 | class PackageSnippets { 32 | 33 | // @start region=isStaticWorkMethod 34 | boolean isStaticWorkMethod(MethodModel method) { 35 | // check static flag first to avoid unnecessary evaluation of UTF-8 entry 36 | return (method.flags().flagsMask() & ClassFile.ACC_STATIC) != 0 37 | // use equalsString to avoid full conversion to String for comparison 38 | // the Utf8Entry can also act as a basic CharSequence without full conversion 39 | // @link substring="methodName" target="MethodModel#methodName" : 40 | && method.methodName().equalsString("work"); // @link substring="equalsString" target="Utf8Entry#equalsString" 41 | } 42 | // @end 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/extras/PreviewFeature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile.extras; 27 | 28 | import java.lang.annotation.*; 29 | 30 | @Target({ElementType.METHOD, 31 | ElementType.CONSTRUCTOR, 32 | ElementType.FIELD, 33 | ElementType.PACKAGE, 34 | ElementType.MODULE, 35 | ElementType.TYPE}) 36 | @Retention(RetentionPolicy.SOURCE) 37 | public @interface PreviewFeature { 38 | Feature feature(); 39 | 40 | enum Feature { 41 | CLASSFILE_API, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/extras/constant/ExtraClassDesc.java: -------------------------------------------------------------------------------- 1 | package io.github.dmlloyd.classfile.extras.constant; 2 | 3 | import java.lang.constant.ClassDesc; 4 | import java.util.Objects; 5 | 6 | /** 7 | * 8 | */ 9 | public final class ExtraClassDesc { 10 | private ExtraClassDesc() {} 11 | 12 | public static ClassDesc ofInternalName(String name) { 13 | ConstantUtils.validateInternalClassName(Objects.requireNonNull(name)); 14 | return ClassDesc.ofDescriptor("L" + name + ";"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/extras/constant/ExtraConstantDescs.java: -------------------------------------------------------------------------------- 1 | package io.github.dmlloyd.classfile.extras.constant; 2 | 3 | /** 4 | * Supplemental (extra) constant desc constants that are not present in Java 17. 5 | */ 6 | public final class ExtraConstantDescs { 7 | public static final String INIT_NAME = ""; 8 | public static final String CLASS_INIT_NAME = ""; 9 | 10 | private ExtraConstantDescs() {} 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/extras/constant/ModuleDesc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.extras.constant; 26 | 27 | import io.github.dmlloyd.classfile.extras.constant.ConstantUtils; 28 | import io.github.dmlloyd.classfile.extras.constant.ModuleDescImpl; 29 | 30 | import static java.util.Objects.requireNonNull; 31 | 32 | /** 33 | * A nominal descriptor for a {@code Module} constant. 34 | * 35 | *

36 | * To create a {@link ModuleDesc} for a module, use the {@link #of(String)} 37 | * method. 38 | * 39 | * @jvms 4.4.11 The CONSTANT_Module_info Structure 40 | * @since 21 41 | */ 42 | public sealed interface ModuleDesc 43 | permits ModuleDescImpl { 44 | 45 | /** 46 | * Returns a {@link ModuleDesc} for a module, 47 | * given the name of the module. 48 | * 49 | * @param name the module name 50 | * @return a {@link ModuleDesc} describing the desired module 51 | * @throws NullPointerException if the argument is {@code null} 52 | * @throws IllegalArgumentException if the name string is not in the 53 | * correct format 54 | * @jvms 4.2.3 Module and Package Names 55 | */ 56 | static ModuleDesc of(String name) { 57 | ConstantUtils.validateModuleName(requireNonNull(name)); 58 | return new ModuleDescImpl(name); 59 | } 60 | 61 | /** 62 | * Returns the module name of this {@link ModuleDesc}. 63 | * 64 | * @return the module name 65 | */ 66 | String name(); 67 | 68 | /** 69 | * Compare the specified object with this descriptor for equality. 70 | * Returns {@code true} if and only if the specified object is 71 | * also a {@link ModuleDesc} and both describe the same module. 72 | * 73 | * @param o the other object 74 | * @return whether this descriptor is equal to the other object 75 | */ 76 | @Override 77 | boolean equals(Object o); 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/extras/constant/ModuleDescImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.extras.constant; 26 | 27 | import io.github.dmlloyd.classfile.extras.constant.ModuleDesc; 28 | 29 | /* 30 | * Implementation of {@code ModuleDesc} 31 | * @param name must have been validated 32 | */ 33 | public record ModuleDescImpl(String name) implements ModuleDesc { 34 | 35 | @Override 36 | public String toString() { 37 | return String.format("ModuleDesc[%s]", name()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/extras/constant/PackageDescImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.extras.constant; 26 | 27 | import io.github.dmlloyd.classfile.extras.constant.PackageDesc; 28 | 29 | /* 30 | * Implementation of {@code PackageDesc} 31 | * @param internalName must have been validated 32 | */ 33 | public record PackageDescImpl(String internalName) implements PackageDesc { 34 | 35 | @Override 36 | public String toString() { 37 | return String.format("PackageDesc[%s]", name()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/AbstractDirectBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.Attribute; 28 | import io.github.dmlloyd.classfile.constantpool.ConstantPool; 29 | 30 | public class AbstractDirectBuilder { 31 | protected final SplitConstantPool constantPool; 32 | protected final ClassFileImpl context; 33 | protected final AttributeHolder attributes = new AttributeHolder(); 34 | protected M original; 35 | 36 | public AbstractDirectBuilder(SplitConstantPool constantPool, ClassFileImpl context) { 37 | this.constantPool = constantPool; 38 | this.context = context; 39 | } 40 | 41 | public SplitConstantPool constantPool() { 42 | return constantPool; 43 | } 44 | 45 | public boolean canWriteDirect(ConstantPool source) { 46 | return constantPool().canWriteDirect(source); 47 | } 48 | 49 | public void setOriginal(M original) { 50 | this.original = original; 51 | } 52 | 53 | public void writeAttribute(Attribute a) { 54 | if (Util.isAttributeAllowed(a, context)) { 55 | attributes.withAttribute(a); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/AbstractElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | public abstract class AbstractElement { 28 | public AbstractElement() { } 29 | 30 | public void writeTo(DirectCodeBuilder builder) { 31 | throw new UnsupportedOperationException(); 32 | } 33 | 34 | public void writeTo(DirectClassBuilder builder) { 35 | throw new UnsupportedOperationException(); 36 | } 37 | 38 | public void writeTo(DirectMethodBuilder builder) { 39 | throw new UnsupportedOperationException(); 40 | } 41 | 42 | public void writeTo(DirectFieldBuilder builder) { 43 | throw new UnsupportedOperationException(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/AbstractUnboundModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.Attribute; 28 | import io.github.dmlloyd.classfile.AttributedElement; 29 | import io.github.dmlloyd.classfile.ClassFileElement; 30 | import io.github.dmlloyd.classfile.CompoundElement; 31 | import java.util.Collections; 32 | import java.util.List; 33 | import java.util.function.Consumer; 34 | import java.util.stream.Stream; 35 | 36 | public abstract sealed class AbstractUnboundModel 37 | extends AbstractElement 38 | implements CompoundElement, AttributedElement 39 | permits BufferedCodeBuilder.Model, BufferedFieldBuilder.Model, BufferedMethodBuilder.Model { 40 | final List elements; 41 | private List> attributes; 42 | 43 | public AbstractUnboundModel(List elements) { 44 | this.elements = Collections.unmodifiableList(elements); 45 | } 46 | 47 | @Override 48 | public void forEach(Consumer consumer) { 49 | elements.forEach(consumer); 50 | } 51 | 52 | @Override 53 | public Stream elementStream() { 54 | return elements.stream(); 55 | } 56 | 57 | @Override 58 | public List elementList() { 59 | return elements; 60 | } 61 | 62 | @Override 63 | public List> attributes() { 64 | if (attributes == null) 65 | attributes = elements.stream() 66 | .>mapMulti((e, sink) -> { 67 | if (e instanceof Attribute attr) { 68 | sink.accept(attr); 69 | } 70 | }) 71 | .toList(); 72 | return attributes; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/AccessFlagsImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.AccessFlags; 28 | import io.github.dmlloyd.classfile.extras.reflect.AccessFlag; 29 | import java.util.Set; 30 | 31 | public final class AccessFlagsImpl extends AbstractElement 32 | implements AccessFlags { 33 | 34 | private final AccessFlag.Location location; 35 | private final int flagsMask; 36 | private Set flags; 37 | 38 | public AccessFlagsImpl(AccessFlag.Location location, AccessFlag... flags) { 39 | this.location = location; 40 | this.flagsMask = Util.flagsToBits(location, flags); 41 | this.flags = Set.of(flags); 42 | } 43 | 44 | public AccessFlagsImpl(AccessFlag.Location location, int mask) { 45 | this.location = location; 46 | this.flagsMask = mask; 47 | } 48 | 49 | @Override 50 | public int flagsMask() { 51 | return flagsMask; 52 | } 53 | 54 | @Override 55 | public Set flags() { 56 | if (flags == null) 57 | flags = AccessFlag.maskToAccessFlags(flagsMask, location); 58 | return flags; 59 | } 60 | 61 | @Override 62 | public void writeTo(DirectClassBuilder builder) { 63 | builder.setFlags(flagsMask); 64 | } 65 | 66 | @Override 67 | public void writeTo(DirectMethodBuilder builder) { 68 | builder.setFlags(flagsMask); 69 | } 70 | 71 | @Override 72 | public void writeTo(DirectFieldBuilder builder) { 73 | builder.setFlags(flagsMask); 74 | } 75 | 76 | @Override 77 | public AccessFlag.Location location() { 78 | return location; 79 | } 80 | 81 | @Override 82 | public boolean has(AccessFlag flag) { 83 | return Util.has(location, flagsMask, flag); 84 | } 85 | 86 | @Override 87 | public String toString() { 88 | return String.format("AccessFlags[flags=%d]", flagsMask); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/BackportUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.dmlloyd.classfile.impl; 2 | 3 | import java.util.function.Function; 4 | import java.util.function.Supplier; 5 | 6 | /** 7 | * Utilities specific to the backport. 8 | */ 9 | public final class BackportUtil { 10 | private BackportUtil() {} 11 | 12 | // this trick helps to keep a smaller diff up above 13 | public static class JLA { 14 | public static int countPositives(byte[] ba, int off, int len) { 15 | int limit = off + len; 16 | for (int i = off; i < limit; i++) { 17 | if (ba[i] < 0) { 18 | return i - off; 19 | } 20 | } 21 | return len; 22 | } 23 | public static void inflateBytesToChars(byte[] src, int srcOff, char[] dst, int dstOff, int len) { 24 | for (int i = 0; i < len; i++) { 25 | dst[dstOff++] = (char) Byte.toUnsignedInt(src[srcOff++]); 26 | } 27 | } 28 | } 29 | 30 | public static class ArraysSupport { 31 | public static int hashCodeOfUnsigned(byte[] a, int fromIndex, int length, int initialValue) { 32 | return switch (length) { 33 | case 0 -> initialValue; 34 | case 1 -> 31 * initialValue + Byte.toUnsignedInt(a[fromIndex]); 35 | default -> unsignedHashCode(initialValue, a, fromIndex, length); 36 | }; 37 | } 38 | private static int unsignedHashCode(int result, byte[] a, int fromIndex, int length) { 39 | int end = fromIndex + length; 40 | for (int i = fromIndex; i < end; i++) { 41 | result = 31 * result + Byte.toUnsignedInt(a[i]); 42 | } 43 | return result; 44 | } 45 | } 46 | 47 | public static T throwAsObj(Function factory, String msg) throws E { 48 | throw factory.apply(msg); 49 | } 50 | 51 | public static T throwAsObj(Supplier factory) throws E { 52 | throw factory.get(); 53 | } 54 | 55 | public static int throwAsInt(Function factory, String msg) throws E { 56 | throw factory.apply(msg); 57 | } 58 | 59 | public static int throwAsInt(Supplier factory) throws E { 60 | throw factory.get(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/BoundCharacterRange.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile.impl; 27 | 28 | import io.github.dmlloyd.classfile.Label; 29 | import io.github.dmlloyd.classfile.instruction.CharacterRange; 30 | 31 | public final class BoundCharacterRange 32 | extends AbstractElement 33 | implements CharacterRange { 34 | 35 | private final CodeImpl code; 36 | private final int offset; 37 | 38 | public BoundCharacterRange(CodeImpl code, int offset) { 39 | this.code = code; 40 | this.offset = offset; 41 | } 42 | 43 | int startPc() { 44 | return code.classReader.readU2(offset); 45 | } 46 | 47 | int endPc() { 48 | return code.classReader.readU2(offset + 2); 49 | } 50 | 51 | @Override 52 | public int characterRangeStart() { 53 | return code.classReader.readInt(offset + 4); 54 | } 55 | 56 | @Override 57 | public int characterRangeEnd() { 58 | return code.classReader.readInt(offset + 8); 59 | } 60 | 61 | @Override 62 | public int flags() { 63 | return code.classReader.readU2(offset + 12); 64 | } 65 | 66 | @Override 67 | public Label startScope() { 68 | return code.getLabel(startPc()); 69 | } 70 | 71 | @Override 72 | public Label endScope() { 73 | return code.getLabel(endPc() + 1); 74 | } 75 | 76 | @Override 77 | public void writeTo(DirectCodeBuilder builder) { 78 | builder.addCharacterRange(this); 79 | } 80 | 81 | @Override 82 | public String toString() { 83 | return String.format("CharacterRange[startScope=%s, endScope=%s, characterRangeStart=%s, characterRangeEnd=%s, flags=%d]", 84 | startScope(), endScope(), characterRangeStart(), characterRangeEnd(), flags()); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/BoundLocalVariable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile.impl; 27 | 28 | import io.github.dmlloyd.classfile.attribute.LocalVariableInfo; 29 | import io.github.dmlloyd.classfile.constantpool.Utf8Entry; 30 | import io.github.dmlloyd.classfile.instruction.LocalVariable; 31 | import java.lang.constant.ClassDesc; 32 | 33 | public final class BoundLocalVariable 34 | extends AbstractBoundLocalVariable 35 | implements LocalVariableInfo, 36 | LocalVariable { 37 | 38 | public BoundLocalVariable(CodeImpl code, int offset) { 39 | super(code, offset); 40 | } 41 | 42 | @Override 43 | public Utf8Entry type() { 44 | return secondaryEntry(); 45 | } 46 | 47 | @Override 48 | public ClassDesc typeSymbol() { 49 | return Util.fieldTypeSymbol(type()); 50 | } 51 | 52 | @Override 53 | public void writeTo(DirectCodeBuilder writer) { 54 | writer.addLocalVariable(this); 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return String.format("LocalVariable[name=%s, slot=%d, type=%s]", name().stringValue(), slot(), type().stringValue()); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/BoundLocalVariableType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.attribute.LocalVariableTypeInfo; 28 | import io.github.dmlloyd.classfile.constantpool.Utf8Entry; 29 | import io.github.dmlloyd.classfile.instruction.LocalVariableType; 30 | 31 | public final class BoundLocalVariableType 32 | extends AbstractBoundLocalVariable 33 | implements LocalVariableTypeInfo, 34 | LocalVariableType { 35 | 36 | public BoundLocalVariableType(CodeImpl code, int offset) { 37 | super(code, offset); 38 | } 39 | 40 | @Override 41 | public Utf8Entry signature() { 42 | return secondaryEntry(); 43 | } 44 | 45 | @Override 46 | public void writeTo(DirectCodeBuilder writer) { 47 | writer.addLocalVariableType(this); 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return String.format("LocalVariableType[name=%s, slot=%d, signature=%s]", name().stringValue(), slot(), signature().stringValue()); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/BoundRecordComponentInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.Attribute; 28 | import io.github.dmlloyd.classfile.ClassReader; 29 | import io.github.dmlloyd.classfile.attribute.RecordComponentInfo; 30 | import io.github.dmlloyd.classfile.constantpool.Utf8Entry; 31 | import java.util.List; 32 | 33 | public final class BoundRecordComponentInfo 34 | implements RecordComponentInfo { 35 | 36 | private final ClassReader reader; 37 | private final int startPos, attributesPos; 38 | private List> attributes; 39 | 40 | public BoundRecordComponentInfo(ClassReader reader, int startPos) { 41 | this.reader = reader; 42 | this.startPos = startPos; 43 | attributesPos = startPos + 4; 44 | } 45 | 46 | @Override 47 | public Utf8Entry name() { 48 | return reader.readEntry(startPos, Utf8Entry.class); 49 | } 50 | 51 | @Override 52 | public Utf8Entry descriptor() { 53 | return reader.readEntry(startPos + 2, Utf8Entry.class); 54 | } 55 | 56 | @Override 57 | public List> attributes() { 58 | if (attributes == null) { 59 | attributes = BoundAttribute.readAttributes(null, reader, attributesPos, reader.customAttributes()); 60 | } 61 | return attributes; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/ChainedCodeBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.CodeBuilder; 28 | import io.github.dmlloyd.classfile.CodeElement; 29 | import io.github.dmlloyd.classfile.Label; 30 | import io.github.dmlloyd.classfile.TypeKind; 31 | import java.util.function.Consumer; 32 | 33 | import static java.util.Objects.requireNonNull; 34 | 35 | public final class ChainedCodeBuilder 36 | extends NonterminalCodeBuilder 37 | implements CodeBuilder { 38 | private final Consumer consumer; 39 | 40 | public ChainedCodeBuilder(CodeBuilder downstream, 41 | Consumer consumer) { 42 | super(downstream); 43 | this.consumer = consumer; 44 | } 45 | 46 | @Override 47 | public Label startLabel() { 48 | return terminal.startLabel(); 49 | } 50 | 51 | @Override 52 | public Label endLabel() { 53 | return terminal.endLabel(); 54 | } 55 | 56 | @Override 57 | public int allocateLocal(TypeKind typeKind) { 58 | return parent.allocateLocal(typeKind); 59 | } 60 | 61 | @Override 62 | public CodeBuilder with(CodeElement element) { 63 | consumer.accept(requireNonNull(element)); 64 | return this; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/ChainedFieldBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.FieldBuilder; 28 | import io.github.dmlloyd.classfile.FieldElement; 29 | import io.github.dmlloyd.classfile.constantpool.ConstantPoolBuilder; 30 | import java.util.function.Consumer; 31 | 32 | import static java.util.Objects.requireNonNull; 33 | 34 | public final class ChainedFieldBuilder implements FieldBuilder { 35 | private final TerminalFieldBuilder terminal; 36 | private final Consumer consumer; 37 | 38 | public ChainedFieldBuilder(FieldBuilder downstream, 39 | Consumer consumer) { 40 | this.consumer = consumer; 41 | this.terminal = downstream instanceof ChainedFieldBuilder cfb ? 42 | cfb.terminal : (TerminalFieldBuilder) downstream; 43 | } 44 | 45 | @Override 46 | public ConstantPoolBuilder constantPool() { 47 | return terminal.constantPool(); 48 | } 49 | 50 | @Override 51 | public FieldBuilder with(FieldElement element) { 52 | consumer.accept(requireNonNull(element)); 53 | return this; 54 | } 55 | 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/ChainedMethodBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.CodeBuilder; 28 | import io.github.dmlloyd.classfile.CodeModel; 29 | import io.github.dmlloyd.classfile.CodeTransform; 30 | import io.github.dmlloyd.classfile.MethodBuilder; 31 | import io.github.dmlloyd.classfile.MethodElement; 32 | import io.github.dmlloyd.classfile.constantpool.ConstantPoolBuilder; 33 | import java.util.function.Consumer; 34 | 35 | import static java.util.Objects.requireNonNull; 36 | 37 | public final class ChainedMethodBuilder implements MethodBuilder { 38 | final TerminalMethodBuilder terminal; 39 | final Consumer consumer; 40 | 41 | public ChainedMethodBuilder(MethodBuilder downstream, 42 | Consumer consumer) { 43 | this.consumer = consumer; 44 | this.terminal = downstream instanceof ChainedMethodBuilder cmb ? 45 | cmb.terminal : (TerminalMethodBuilder) downstream; 46 | } 47 | 48 | @Override 49 | public MethodBuilder with(MethodElement element) { 50 | consumer.accept(requireNonNull(element)); 51 | return this; 52 | } 53 | 54 | @Override 55 | public MethodBuilder withCode(Consumer handler) { 56 | consumer.accept(terminal.bufferedCodeBuilder(null) 57 | .run(handler) 58 | .toModel()); 59 | return this; 60 | } 61 | 62 | @Override 63 | public MethodBuilder transformCode(CodeModel code, CodeTransform transform) { 64 | BufferedCodeBuilder builder = terminal.bufferedCodeBuilder(code); 65 | builder.transform(code, transform); 66 | consumer.accept(builder.toModel()); 67 | return this; 68 | } 69 | 70 | @Override 71 | public ConstantPoolBuilder constantPool() { 72 | return terminal.constantPool(); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/ClassFileVersionImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.ClassFileVersion; 28 | 29 | public final class ClassFileVersionImpl 30 | extends AbstractElement 31 | implements ClassFileVersion { 32 | private final int majorVersion, minorVersion; 33 | 34 | public ClassFileVersionImpl(int majorVersion, int minorVersion) { 35 | this.majorVersion = majorVersion; 36 | this.minorVersion = minorVersion; 37 | } 38 | 39 | @Override 40 | public int majorVersion() { 41 | return majorVersion; 42 | } 43 | 44 | @Override 45 | public int minorVersion() { 46 | return minorVersion; 47 | } 48 | 49 | @Override 50 | public void writeTo(DirectClassBuilder builder) { 51 | builder.setVersion(majorVersion, minorVersion); 52 | } 53 | 54 | @Override 55 | public String toString() { 56 | return String.format("ClassFileVersion[majorVersion=%d, minorVersion=%d]", majorVersion, minorVersion); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/DirectFieldBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package io.github.dmlloyd.classfile.impl; 27 | 28 | import io.github.dmlloyd.classfile.CustomAttribute; 29 | import io.github.dmlloyd.classfile.FieldBuilder; 30 | import io.github.dmlloyd.classfile.FieldElement; 31 | import io.github.dmlloyd.classfile.FieldModel; 32 | import io.github.dmlloyd.classfile.constantpool.Utf8Entry; 33 | import java.util.function.Consumer; 34 | 35 | import static java.util.Objects.requireNonNull; 36 | 37 | public final class DirectFieldBuilder 38 | extends AbstractDirectBuilder 39 | implements TerminalFieldBuilder, Util.Writable { 40 | private final Utf8Entry name; 41 | private final Utf8Entry desc; 42 | private int flags; 43 | 44 | public DirectFieldBuilder(SplitConstantPool constantPool, 45 | ClassFileImpl context, 46 | Utf8Entry name, 47 | Utf8Entry type, 48 | int flags, 49 | FieldModel original) { 50 | super(constantPool, context); 51 | setOriginal(original); 52 | this.name = requireNonNull(name); 53 | this.desc = requireNonNull(type); 54 | this.flags = flags; 55 | } 56 | 57 | @Override 58 | public FieldBuilder with(FieldElement element) { 59 | if (element instanceof AbstractElement ae) { 60 | ae.writeTo(this); 61 | } else { 62 | writeAttribute((CustomAttribute) requireNonNull(element)); 63 | } 64 | return this; 65 | } 66 | 67 | public DirectFieldBuilder run(Consumer handler) { 68 | handler.accept(this); 69 | return this; 70 | } 71 | 72 | @Override 73 | public FieldBuilder withFlags(int flags) { 74 | setFlags(flags); 75 | return this; 76 | } 77 | 78 | void setFlags(int flags) { 79 | this.flags = flags; 80 | } 81 | 82 | @Override 83 | public void writeTo(BufWriterImpl buf) { 84 | buf.writeU2U2U2(flags, buf.cpIndex(name), buf.cpIndex(desc)); 85 | attributes.writeTo(buf); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/InterfacesImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.Interfaces; 28 | import io.github.dmlloyd.classfile.constantpool.ClassEntry; 29 | import java.util.List; 30 | import java.util.stream.Collectors; 31 | 32 | public final class InterfacesImpl 33 | extends AbstractElement 34 | implements Interfaces { 35 | private final List interfaces; 36 | 37 | public InterfacesImpl(List interfaces) { 38 | this.interfaces = List.copyOf(interfaces); 39 | } 40 | 41 | @Override 42 | public List interfaces() { 43 | return interfaces; 44 | } 45 | 46 | @Override 47 | public void writeTo(DirectClassBuilder builder) { 48 | builder.setInterfaces(interfaces); 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return String.format("Interfaces[interfaces=%s]", interfaces.stream() 54 | .map(iface -> iface.name().stringValue()) 55 | .collect(Collectors.joining(", "))); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/LabelContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.Label; 28 | 29 | public sealed interface LabelContext 30 | permits TerminalCodeBuilder, CodeImpl { 31 | Label newLabel(); 32 | Label getLabel(int bci); 33 | void setLabelTarget(Label label, int bci); 34 | int labelToBci(Label label); 35 | default boolean canWriteDirect(LabelContext original) { return false; } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/LabelImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.Label; 28 | import io.github.dmlloyd.classfile.instruction.LabelTarget; 29 | 30 | /** 31 | * Labels are created with a parent context, which is either a code attribute 32 | * or a code builder. A label originating in a code attribute context may be 33 | * reused in a code builder context, but only labels from a single code 34 | * attribute may be reused by a single code builder. Mappings to and from 35 | * BCI are the responsibility of the context in which it is used; a single 36 | * word of mutable state is provided, for the exclusive use of the owning 37 | * context. 38 | * 39 | * In practice, this means that labels created in a code attribute can simply 40 | * store the BCI in the state on creation, and labels created in in a code 41 | * builder can store the BCI in the state when the label is eventually set; if 42 | * a code attribute label is reused in a builder, the original BCI can be used 43 | * as an index into an array. 44 | */ 45 | public final class LabelImpl 46 | extends AbstractElement 47 | implements Label, LabelTarget { 48 | 49 | private final LabelContext labelContext; 50 | private int bci; 51 | 52 | public LabelImpl(LabelContext labelContext, int bci) { 53 | this.labelContext = labelContext; 54 | this.bci = bci; 55 | } 56 | 57 | public LabelContext labelContext() { 58 | return labelContext; 59 | } 60 | 61 | public int getBCI() { 62 | return bci; 63 | } 64 | 65 | public void setBCI(int bci) { 66 | this.bci = bci; 67 | } 68 | 69 | @Override 70 | public Label label() { 71 | return this; 72 | } 73 | 74 | @Override 75 | public void writeTo(DirectCodeBuilder builder) { 76 | builder.setLabelTarget(this); 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | return String.format("Label[context=%s, bci=%d]", labelContext, bci); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/impl/LineNumberImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.impl; 26 | 27 | import io.github.dmlloyd.classfile.instruction.LineNumber; 28 | 29 | public final class LineNumberImpl 30 | extends AbstractElement 31 | implements LineNumber { 32 | private static final int INTERN_LIMIT = 1000; 33 | private static final LineNumber[] internCache = new LineNumber[INTERN_LIMIT]; 34 | static { 35 | for (int i=0; i 38 | * A branch instruction is composite: 39 | * {@snippet lang=text : 40 | * // @link substring="BranchInstruction" target="#of": 41 | * BranchInstruction( 42 | * Opcode opcode, // @link substring="opcode" target="#opcode()" 43 | * Label target // @link substring="target" target="#target()" 44 | * ) 45 | * } 46 | *

47 | * Due to physical restrictions, some types of instructions cannot encode labels 48 | * too far away in the list of code elements. In such cases, the {@link 49 | * ClassFile.ShortJumpsOption} controls how an invalid branch instruction model 50 | * is written by a {@link CodeBuilder}. 51 | * 52 | * @see Opcode.Kind#BRANCH 53 | * @see CodeBuilder#branch CodeBuilder::branch 54 | * @see ClassFile.ShortJumpsOption 55 | * @since 24 56 | */ 57 | public sealed interface BranchInstruction extends Instruction 58 | permits AbstractInstruction.BoundBranchInstruction, 59 | AbstractInstruction.UnboundBranchInstruction { 60 | /** 61 | * {@return the branch target of this instruction} 62 | */ 63 | Label target(); 64 | 65 | /** 66 | * {@return a branch instruction} 67 | * 68 | * @param op the opcode for the specific type of branch instruction, 69 | * which must be of kind {@link Opcode.Kind#BRANCH} 70 | * @param target the target of the branch 71 | * @throws IllegalArgumentException if the opcode kind is not 72 | * {@link Opcode.Kind#BRANCH} 73 | */ 74 | static BranchInstruction of(Opcode op, Label target) { 75 | Util.checkKind(op, Opcode.Kind.BRANCH); 76 | return new AbstractInstruction.UnboundBranchInstruction(op, target); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/instruction/LabelTarget.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.instruction; 26 | 27 | import io.github.dmlloyd.classfile.CodeBuilder; 28 | import io.github.dmlloyd.classfile.CodeElement; 29 | import io.github.dmlloyd.classfile.CodeModel; 30 | import io.github.dmlloyd.classfile.CodeTransform; 31 | import io.github.dmlloyd.classfile.Label; 32 | import io.github.dmlloyd.classfile.PseudoInstruction; 33 | import io.github.dmlloyd.classfile.attribute.CodeAttribute; 34 | 35 | import io.github.dmlloyd.classfile.impl.LabelImpl; 36 | 37 | /** 38 | * A pseudo-instruction which indicates that the specified label corresponds to 39 | * the current position in the {@code Code} attribute. Delivered as a {@link 40 | * CodeElement} during traversal of the elements of a {@link CodeModel}. 41 | *

42 | * This can be used to inspect the target position of labels across {@linkplain 43 | * CodeTransform transformations}, as {@linkplain CodeAttribute#labelToBci bci} 44 | * is not stable. 45 | *

46 | * When passed to a {@link CodeBuilder}, this pseudo-instruction sets the 47 | * specified label to be bound at the current position in the builder. 48 | *

49 | * By design, {@code LabelTarget} cannot be created by users and can only be 50 | * read from a code model. Use {@link CodeBuilder#labelBinding 51 | * CodeBuilder::labelBinding} to bind arbitrary labels to a {@code CodeBuilder}. 52 | *

53 | * For a {@code CodeBuilder cob}, a {@code LabelTarget lt}, these two calls are 54 | * equivalent: 55 | * {@snippet lang=java : 56 | * cob.with(lt); // @link substring="with" target="CodeBuilder#with" 57 | * // @link substring="labelBinding" target="CodeBuilder#labelBinding" : 58 | * cob.labelBinding(lt.label()); // @link regex="label(?=\()" target="#label" 59 | * } 60 | * 61 | * @see Label 62 | * @see CodeBuilder#labelBinding CodeBuilder::labelBinding 63 | * @since 24 64 | */ 65 | public sealed interface LabelTarget extends PseudoInstruction 66 | permits LabelImpl { 67 | 68 | /** 69 | * {@return the label corresponding to this target} 70 | */ 71 | Label label(); 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/instruction/MonitorInstruction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.instruction; 26 | 27 | import io.github.dmlloyd.classfile.CodeBuilder; 28 | import io.github.dmlloyd.classfile.CodeElement; 29 | import io.github.dmlloyd.classfile.CodeModel; 30 | import io.github.dmlloyd.classfile.Instruction; 31 | import io.github.dmlloyd.classfile.Opcode; 32 | 33 | import io.github.dmlloyd.classfile.impl.AbstractInstruction; 34 | import io.github.dmlloyd.classfile.impl.Util; 35 | 36 | /** 37 | * Models a {@link Opcode#MONITORENTER monitorenter} or {@link Opcode#MONITOREXIT 38 | * monitorexit} instruction in the {@code code} array of a {@code Code} attribute. 39 | * Corresponding opcodes have a {@linkplain Opcode#kind() kind} of {@link 40 | * Opcode.Kind#MONITOR}. Delivered as a {@link CodeElement} when traversing the 41 | * elements of a {@link CodeModel}. 42 | *

43 | * A monitor instruction is composite: 44 | * {@snippet lang=text : 45 | * // @link substring="MonitorInstruction" target="#of(Opcode)" : 46 | * MonitorInstruction(Opcode opcode) // @link substring="opcode" target="#opcode" 47 | * } 48 | * 49 | * @since 24 50 | */ 51 | public sealed interface MonitorInstruction extends Instruction 52 | permits AbstractInstruction.UnboundMonitorInstruction { 53 | 54 | /** 55 | * {@return a monitor instruction} 56 | * 57 | * @param op the opcode for the specific type of monitor instruction, 58 | * which must be of kind {@link Opcode.Kind#MONITOR} 59 | * @throws IllegalArgumentException if the opcode kind is not 60 | * {@link Opcode.Kind#MONITOR}. 61 | */ 62 | static MonitorInstruction of(Opcode op) { 63 | Util.checkKind(op, Opcode.Kind.MONITOR); 64 | return new AbstractInstruction.UnboundMonitorInstruction(op); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/instruction/NewObjectInstruction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.instruction; 26 | 27 | import io.github.dmlloyd.classfile.CodeBuilder; 28 | import io.github.dmlloyd.classfile.CodeElement; 29 | import io.github.dmlloyd.classfile.CodeModel; 30 | import io.github.dmlloyd.classfile.Instruction; 31 | import io.github.dmlloyd.classfile.Opcode; 32 | import io.github.dmlloyd.classfile.constantpool.ClassEntry; 33 | 34 | import io.github.dmlloyd.classfile.impl.AbstractInstruction; 35 | 36 | /** 37 | * Models a {@link Opcode#NEW new} instruction in the {@code code} array of a {@code Code} 38 | * attribute. Delivered as a {@link CodeElement} when traversing the elements 39 | * of a {@link CodeModel}. 40 | *

41 | * A new object instruction is composite: 42 | * {@snippet lang=text : 43 | * // @link substring="NewObjectInstruction" target="#of" : 44 | * NewObjectInstruction(ClassEntry className) // @link substring="className" target="#className" 45 | * } 46 | * where the {@code className} is a non-abstract class. 47 | * 48 | * @see Opcode.Kind#NEW_OBJECT 49 | * @see CodeBuilder#new_ CodeBuilder::new_ 50 | * @jvms 6.5.new new 51 | * @since 24 52 | */ 53 | public sealed interface NewObjectInstruction extends Instruction 54 | permits AbstractInstruction.BoundNewObjectInstruction, AbstractInstruction.UnboundNewObjectInstruction { 55 | 56 | /** 57 | * {@return the type of object to create} 58 | */ 59 | ClassEntry className(); 60 | 61 | /** 62 | * {@return a new object instruction} 63 | * 64 | * @param className the type of object to create 65 | */ 66 | static NewObjectInstruction of(ClassEntry className) { 67 | return new AbstractInstruction.UnboundNewObjectInstruction(className); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/instruction/NewReferenceArrayInstruction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.instruction; 26 | 27 | import io.github.dmlloyd.classfile.CodeBuilder; 28 | import io.github.dmlloyd.classfile.CodeElement; 29 | import io.github.dmlloyd.classfile.CodeModel; 30 | import io.github.dmlloyd.classfile.Instruction; 31 | import io.github.dmlloyd.classfile.Opcode; 32 | import io.github.dmlloyd.classfile.constantpool.ClassEntry; 33 | 34 | import io.github.dmlloyd.classfile.impl.AbstractInstruction; 35 | 36 | /** 37 | * Models a {@link Opcode#ANEWARRAY anewarray} instruction in the {@code code} 38 | * array of a {@code Code} attribute. Delivered as a {@link CodeElement} 39 | * when traversing the elements of a {@link CodeModel}. 40 | *

41 | * A new reference array instruction is composite: 42 | * {@snippet lang=text : 43 | * // @link substring="NewReferenceArrayInstruction" target="#of" : 44 | * NewReferenceArrayInstruction(ClassEntry componentType) // @link substring="componentType" target="#componentType" 45 | * } 46 | * 47 | * @see Opcode.Kind#NEW_REF_ARRAY 48 | * @see CodeBuilder#newarray CodeBuilder::anewarray 49 | * @jvms 6.5.anewarray anewarray 50 | * @since 24 51 | */ 52 | public sealed interface NewReferenceArrayInstruction extends Instruction 53 | permits AbstractInstruction.BoundNewReferenceArrayInstruction, AbstractInstruction.UnboundNewReferenceArrayInstruction { 54 | /** 55 | * {@return the component type of the array} 56 | */ 57 | ClassEntry componentType(); 58 | 59 | /** 60 | * {@return a new reference array instruction} 61 | * 62 | * @param componentType the component type of the array 63 | */ 64 | static NewReferenceArrayInstruction of(ClassEntry componentType) { 65 | return new AbstractInstruction.UnboundNewReferenceArrayInstruction(componentType); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/instruction/NopInstruction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.instruction; 26 | 27 | import io.github.dmlloyd.classfile.CodeBuilder; 28 | import io.github.dmlloyd.classfile.CodeElement; 29 | import io.github.dmlloyd.classfile.CodeModel; 30 | import io.github.dmlloyd.classfile.Instruction; 31 | import io.github.dmlloyd.classfile.Opcode; 32 | 33 | import io.github.dmlloyd.classfile.impl.AbstractInstruction; 34 | 35 | /** 36 | * Models a {@link Opcode#NOP nop} instruction in the {@code code} 37 | * array of a {@code Code} attribute. Delivered as a {@link CodeElement} 38 | * when traversing the elements of a {@link CodeModel}. 39 | *

40 | * A no-op instruction has no visible state. 41 | * 42 | * @see CodeBuilder#nop CodeBuilder::nop 43 | * @jvms 6.5.nop nop 44 | * @since 24 45 | */ 46 | public sealed interface NopInstruction extends Instruction 47 | permits AbstractInstruction.UnboundNopInstruction { 48 | /** 49 | * {@return a no-op instruction} 50 | */ 51 | static NopInstruction of() { 52 | return new AbstractInstruction.UnboundNopInstruction(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/instruction/OperatorInstruction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.instruction; 26 | 27 | import io.github.dmlloyd.classfile.CodeElement; 28 | import io.github.dmlloyd.classfile.CodeModel; 29 | import io.github.dmlloyd.classfile.Instruction; 30 | import io.github.dmlloyd.classfile.Opcode; 31 | import io.github.dmlloyd.classfile.TypeKind; 32 | 33 | import io.github.dmlloyd.classfile.impl.AbstractInstruction; 34 | import io.github.dmlloyd.classfile.impl.Util; 35 | 36 | /** 37 | * Models an arithmetic operator instruction in the {@code code} array of a 38 | * {@code Code} attribute. Corresponding opcodes have a {@linkplain Opcode#kind() kind} of 39 | * {@link Opcode.Kind#OPERATOR}. Delivered as a {@link CodeElement} when 40 | * traversing the elements of a {@link CodeModel}. 41 | *

42 | * An operator instruction is composite: 43 | * {@snippet lang=text : 44 | * // @link substring="OperatorInstruction" target="#of" : 45 | * OperatorInstruction(Opcode opcode) // @link substring="opcode" target="#opcode()" 46 | * } 47 | * 48 | * @see Opcode.Kind#OPERATOR 49 | * @since 24 50 | */ 51 | public sealed interface OperatorInstruction extends Instruction 52 | permits AbstractInstruction.UnboundOperatorInstruction { 53 | /** 54 | * {@return the operand type of the instruction} 55 | * This is derived from the {@link #opcode opcode}. 56 | */ 57 | TypeKind typeKind(); 58 | 59 | /** 60 | * {@return an operator instruction} 61 | * 62 | * @param op the opcode for the specific type of operator instruction, 63 | * which must be of kind {@link Opcode.Kind#OPERATOR} 64 | * @throws IllegalArgumentException if the opcode kind is not 65 | * {@link Opcode.Kind#OPERATOR}. 66 | */ 67 | static OperatorInstruction of(Opcode op) { 68 | Util.checkKind(op, Opcode.Kind.OPERATOR); 69 | return new AbstractInstruction.UnboundOperatorInstruction(op); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/instruction/StackInstruction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.instruction; 26 | 27 | import io.github.dmlloyd.classfile.CodeElement; 28 | import io.github.dmlloyd.classfile.CodeModel; 29 | import io.github.dmlloyd.classfile.Instruction; 30 | import io.github.dmlloyd.classfile.Opcode; 31 | 32 | import io.github.dmlloyd.classfile.impl.AbstractInstruction; 33 | import io.github.dmlloyd.classfile.impl.Util; 34 | 35 | /** 36 | * Models a stack manipulation instruction in the {@code code} array of a 37 | * {@code Code} attribute. Corresponding opcodes have a {@linkplain Opcode#kind() kind} of 38 | * {@link Opcode.Kind#STACK}. Delivered as a {@link CodeElement} when 39 | * traversing the elements of a {@link CodeModel}. 40 | *

41 | * A stack manipulation instruction is composite: 42 | * {@snippet lang=text : 43 | * // @link substring="StackInstruction" target="#of" : 44 | * StackInstruction(Opcode opcode) // @link substring="opcode" target="#opcode()" 45 | * } 46 | * 47 | * @see Opcode.Kind#STACK 48 | * @since 24 49 | */ 50 | public sealed interface StackInstruction extends Instruction 51 | permits AbstractInstruction.UnboundStackInstruction { 52 | 53 | /** 54 | * {@return a stack manipulation instruction} 55 | * 56 | * @param op the opcode for the specific type of stack instruction, 57 | * which must be of kind {@link Opcode.Kind#STACK} 58 | * @throws IllegalArgumentException if the opcode kind is not 59 | * {@link Opcode.Kind#STACK}. 60 | */ 61 | static StackInstruction of(Opcode op) { 62 | Util.checkKind(op, Opcode.Kind.STACK); 63 | return new AbstractInstruction.UnboundStackInstruction(op); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/instruction/SwitchCase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.instruction; 26 | 27 | import io.github.dmlloyd.classfile.Label; 28 | 29 | import io.github.dmlloyd.classfile.impl.AbstractInstruction; 30 | 31 | /** 32 | * Models a single case in a {@link LookupSwitchInstruction lookupswitch} or 33 | * {@link TableSwitchInstruction tableswitch} instruction. 34 | *

35 | * A switch case is composite: 36 | * {@snippet lang=text : 37 | * // @link substring="SwitchCase" target="#of" : 38 | * SwitchCase( 39 | * int caseValue, // @link substring="caseValue" target="#caseValue" 40 | * Label target // @link substring="target" target="#target" 41 | * ) 42 | * } 43 | * 44 | * @see LookupSwitchInstruction 45 | * @see TableSwitchInstruction 46 | * @since 24 47 | */ 48 | public sealed interface SwitchCase 49 | permits AbstractInstruction.SwitchCaseImpl { 50 | 51 | /** {@return the integer value corresponding to this case} */ 52 | int caseValue(); 53 | 54 | /** {@return the branch target corresponding to this case} */ 55 | Label target(); 56 | 57 | /** 58 | * {@return a new switch case} 59 | * 60 | * @param caseValue the integer value for the case 61 | * @param target the branch target for the case 62 | */ 63 | static SwitchCase of(int caseValue, Label target) { 64 | return new AbstractInstruction.SwitchCaseImpl(caseValue, target); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/io/github/dmlloyd/classfile/instruction/ThrowInstruction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package io.github.dmlloyd.classfile.instruction; 26 | 27 | import io.github.dmlloyd.classfile.CodeBuilder; 28 | import io.github.dmlloyd.classfile.CodeElement; 29 | import io.github.dmlloyd.classfile.CodeModel; 30 | import io.github.dmlloyd.classfile.Instruction; 31 | import io.github.dmlloyd.classfile.Opcode; 32 | 33 | import io.github.dmlloyd.classfile.impl.AbstractInstruction; 34 | 35 | /** 36 | * Models an {@link Opcode#ATHROW athrow} instruction in the {@code code} array of a 37 | * {@code Code} attribute. Delivered as a {@link CodeElement} when traversing 38 | * the elements of a {@link CodeModel}. 39 | *

40 | * A throw instruction has no visible state. 41 | * 42 | * @see Opcode.Kind#THROW_EXCEPTION 43 | * @see CodeBuilder#athrow CodeBuiler::athrow 44 | * @since 24 45 | */ 46 | public sealed interface ThrowInstruction extends Instruction 47 | permits AbstractInstruction.UnboundThrowInstruction { 48 | 49 | /** 50 | * {@return a throw instruction} 51 | */ 52 | static ThrowInstruction of() { 53 | return new AbstractInstruction.UnboundThrowInstruction(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module io.github.dmlloyd.classfile { 2 | exports io.github.dmlloyd.classfile; 3 | exports io.github.dmlloyd.classfile.attribute; 4 | exports io.github.dmlloyd.classfile.constantpool; 5 | exports io.github.dmlloyd.classfile.extras; 6 | exports io.github.dmlloyd.classfile.extras.constant; 7 | exports io.github.dmlloyd.classfile.extras.reflect; 8 | exports io.github.dmlloyd.classfile.instruction; 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/io/github/dmlloyd/classfile/tests/SimpleTests.java: -------------------------------------------------------------------------------- 1 | package io.github.dmlloyd.classfile.tests; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertTrue; 4 | 5 | import java.io.InputStream; 6 | import java.util.Objects; 7 | 8 | import io.github.dmlloyd.classfile.ClassModel; 9 | import io.github.dmlloyd.classfile.ClassTransform; 10 | import io.github.dmlloyd.classfile.ClassFile; 11 | import io.github.dmlloyd.classfile.MethodModel; 12 | import io.github.dmlloyd.classfile.extras.reflect.AccessFlag; 13 | import org.junit.jupiter.api.Test; 14 | 15 | /** 16 | * 17 | */ 18 | public final class SimpleTests { 19 | @Test 20 | public void testParse() throws Exception { 21 | byte[] b; 22 | try (InputStream is = Objects.requireNonNullElseGet(SimpleTests.class.getClassLoader().getResourceAsStream(SimpleTests.class.getName().replace('.', '/') + ".class"), InputStream::nullInputStream)) { 23 | b = is.readAllBytes(); 24 | } 25 | ClassModel model = ClassFile.of().parse(b); 26 | assertTrue(model.thisClass().name().equalsString(SimpleTests.class.getName().replace('.', '/'))); 27 | boolean ok = false; 28 | for (MethodModel method : model.methods()) { 29 | if (method.methodName().equalsString("testParse")) { 30 | ok = true; 31 | assertTrue(method.flags().has(AccessFlag.PUBLIC)); 32 | } 33 | } 34 | assertTrue(ok, "Didn't find the testParse method"); 35 | ClassFile.of().transformClass(model, ClassTransform.ACCEPT_ALL); 36 | } 37 | } 38 | --------------------------------------------------------------------------------