Fork of the Fernflower decompiler
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fernflower/src/org/jetbrains/java/decompiler/struct/attr/StructModuleAttribute.java

165 lines
6.1 KiB

// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.java.decompiler.struct.attr;
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
import org.jetbrains.java.decompiler.util.DataInputFullStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class StructModuleAttribute extends StructGeneralAttribute {
public String moduleName;
public int moduleFlags;
public String moduleVersion;
public List<RequiresEntry> requires;
public List<ExportsEntry> exports;
public List<OpensEntry> opens;
public List<String> uses;
public List<ProvidesEntry> provides;
@Override
public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException {
int moduleNameIndex = data.readUnsignedShort();
this.moduleName = pool.getPrimitiveConstant(moduleNameIndex).getString();
this.moduleFlags = data.readUnsignedShort();
int moduleVersionIndex = data.readUnsignedShort();
if (moduleVersionIndex != 0) {
moduleVersion = pool.getPrimitiveConstant(moduleVersionIndex).getString();
}
this.requires = readRequires(data, pool);
this.exports = readExports(data, pool);
this.opens = readOpens(data, pool);
this.uses = readUses(data, pool);
this.provides = readProvides(data, pool);
}
public List<RequiresEntry> readRequires(DataInputFullStream data, ConstantPool pool) throws IOException {
int requiresCount = data.readUnsignedShort();
if (requiresCount <= 0) return Collections.emptyList();
List<RequiresEntry> requires = new ArrayList<>(requiresCount);
for (int i = 0; i < requiresCount; i++) {
int moduleNameIndex = data.readUnsignedShort();
int requiresFlags = data.readUnsignedShort();
int versionIndex = data.readUnsignedShort();
String moduleName = pool.getPrimitiveConstant(moduleNameIndex).getString();
String version = versionIndex == 0 ? null : pool.getPrimitiveConstant(versionIndex).getString();
requires.add(new RequiresEntry(moduleName, requiresFlags, version));
}
return requires;
}
private static List<ExportsEntry> readExports(DataInputFullStream data, ConstantPool pool) throws IOException {
int exportsCount = data.readUnsignedShort();
if (exportsCount <= 0) return Collections.emptyList();
List<ExportsEntry> exports = new ArrayList<>(exportsCount);
for (int i = 0; i < exportsCount; i++) {
int packageNameIndex = data.readUnsignedShort();
int exportsFlags = data.readUnsignedShort();
List<String> exportsToModules = readStringList(data, pool);
String packageName = pool.getPrimitiveConstant(packageNameIndex).getString();
exports.add(new ExportsEntry(packageName, exportsFlags, exportsToModules));
}
return exports;
}
private static List<OpensEntry> readOpens(DataInputFullStream data, ConstantPool pool) throws IOException {
int opensCount = data.readUnsignedShort();
if (opensCount <= 0) return Collections.emptyList();
List<OpensEntry> opens = new ArrayList<>(opensCount);
for (int i = 0; i < opensCount; i++) {
int packageNameIndex = data.readUnsignedShort();
int opensFlags = data.readUnsignedShort();
List<String> opensToModules = readStringList(data, pool);
String packageName = pool.getPrimitiveConstant(packageNameIndex).getString();
opens.add(new OpensEntry(packageName, opensFlags, opensToModules));
}
return opens;
}
private static List<String> readUses(DataInputFullStream data, ConstantPool pool) throws IOException {
return readStringList(data, pool);
}
private static List<ProvidesEntry> readProvides(DataInputFullStream data, ConstantPool pool) throws IOException {
int providesCount = data.readUnsignedShort();
if (providesCount <= 0) return Collections.emptyList();
List<ProvidesEntry> provides = new ArrayList<>(providesCount);
for (int i = 0; i < providesCount; i++) {
int interfaceNameIndex = data.readUnsignedShort();
String interfaceName = pool.getPrimitiveConstant(interfaceNameIndex).getString();
List<String> implementationNames = readStringList(data, pool);
provides.add(new ProvidesEntry(interfaceName, implementationNames));
}
return provides;
}
private static List<String> readStringList(DataInputFullStream data, ConstantPool pool) throws IOException {
int count = data.readUnsignedShort();
if (count <= 0) {
return Collections.emptyList();
}
else {
List<String> strings = new ArrayList<>(count);
for (int i = 0; i < count; i++) {
int index = data.readUnsignedShort();
strings.add(pool.getPrimitiveConstant(index).getString());
}
return strings;
}
}
public static final class RequiresEntry {
public final String moduleName;
public final int flags;
public final String moduleVersion;
public RequiresEntry(String moduleName, int flags, String moduleVersion) {
this.moduleName = moduleName;
this.flags = flags;
this.moduleVersion = moduleVersion;
}
}
public static final class ExportsEntry {
public final String packageName;
public final int flags;
public final List<String> exportToModules;
public ExportsEntry(String packageName, int flags, List<String> exportToModules) {
this.packageName = packageName;
this.flags = flags;
this.exportToModules = exportToModules;
}
}
public static final class OpensEntry {
public final String packageName;
public final int flags;
public final List<String> opensToModules;
public OpensEntry(String packageName, int flags, List<String> exportToModules) {
this.packageName = packageName;
this.flags = flags;
this.opensToModules = exportToModules;
}
}
public static final class ProvidesEntry {
public final String interfaceName;
public final List<String> implementationNames;
public ProvidesEntry(String interfaceName, List<String> implementationNames) {
this.interfaceName = interfaceName;
this.implementationNames = implementationNames;
}
}
}