mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +01:00
Add support for partial classes
This commit is contained in:
parent
7894963612
commit
4872dd137a
@ -19,6 +19,8 @@ package de.inetsoftware.classparser;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
@ -48,9 +50,9 @@ public class ClassFile {
|
||||
|
||||
private final ConstantClass[] interfaces;
|
||||
|
||||
private final FieldInfo[] fields;
|
||||
private FieldInfo[] fields;
|
||||
|
||||
private final MethodInfo[] methods;
|
||||
private MethodInfo[] methods;
|
||||
|
||||
private final Attributes attributes;
|
||||
|
||||
@ -136,16 +138,27 @@ public class ClassFile {
|
||||
methods = classFile.methods;
|
||||
attributes = classFile.attributes;
|
||||
|
||||
patchConstantPool( classFile.thisClass.getName(), thisClass );
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the reference to the Class in the the constant pool.
|
||||
*
|
||||
* @param origClassName
|
||||
* the class name that should be replaced.
|
||||
* @param thisClass
|
||||
* the reference of the class that should be used.
|
||||
*/
|
||||
private void patchConstantPool( String origClassName, ConstantClass thisClass ) {
|
||||
// patch constant pool
|
||||
String origClassName = classFile.thisClass.getName();
|
||||
for( int i = 0; i < constantPool.size(); i++ ) {
|
||||
Object obj = constantPool.get( i );
|
||||
if( obj instanceof ConstantClass ) {
|
||||
if( ((ConstantClass)obj).getName().equals( origClassName ) ) {
|
||||
constantPool.set( i, thisClass );
|
||||
}
|
||||
} else if( obj instanceof ConstantFieldRef ) {
|
||||
ConstantFieldRef ref = (ConstantFieldRef)obj;
|
||||
} else if( obj instanceof ConstantRef ) {
|
||||
ConstantRef ref = (ConstantRef)obj;
|
||||
if( ref.getClassName().equals( origClassName ) ) {
|
||||
ConstantNameAndType nameAndType = new ConstantNameAndType( ref.getName(), ref.getType() );
|
||||
constantPool.set( i, new ConstantFieldRef( thisClass, nameAndType ) );
|
||||
@ -301,4 +314,31 @@ public class ClassFile {
|
||||
public static enum Type {
|
||||
Class, Interface, Enum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends this class with the methods and fields of the partial class.
|
||||
*
|
||||
* @param partialClassFile
|
||||
* extension of the class
|
||||
*/
|
||||
public void partial( ClassFile partialClassFile ) {
|
||||
ArrayList<MethodInfo> allMethods = new ArrayList<>( Arrays.asList( methods ) );
|
||||
for( MethodInfo m : partialClassFile.methods ) {
|
||||
if( getMethod( m.getName(), m.getType() ) == null ) {
|
||||
m.setDeclaringClassFile( this );
|
||||
allMethods.add( m );
|
||||
}
|
||||
}
|
||||
methods = allMethods.toArray( methods );
|
||||
|
||||
ArrayList<FieldInfo> allFields = new ArrayList<>( Arrays.asList( fields ) );
|
||||
for( FieldInfo field : partialClassFile.fields ) {
|
||||
if( getField( field.getName() ) == null ) {
|
||||
allFields.add( field );
|
||||
}
|
||||
}
|
||||
fields = allFields.toArray( fields );
|
||||
|
||||
partialClassFile.patchConstantPool( partialClassFile.thisClass.getName(), thisClass );
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2011 - 2019 Volker Berlin (i-net software)
|
||||
Copyright 2011 - 2020 Volker Berlin (i-net software)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -21,6 +21,7 @@ import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import de.inetsoftware.classparser.Attributes.AttributeInfo;
|
||||
@ -200,4 +201,14 @@ public class MethodInfo implements Member {
|
||||
public ConstantPool getConstantPool() {
|
||||
return constantPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the reference to the ClassFile
|
||||
*
|
||||
* @param classFile
|
||||
* the new value
|
||||
*/
|
||||
void setDeclaringClassFile( @Nonnull ClassFile classFile ) {
|
||||
this.classFile = classFile;
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +88,11 @@ public class JWebAssembly {
|
||||
*/
|
||||
public static final String REPLACE_ANNOTATION = "de.inetsoftware.jwebassembly.api.annotation.Replace";
|
||||
|
||||
/**
|
||||
* The name of the annotation for partial class another class of the Java runtime.
|
||||
*/
|
||||
public static final String PARTIAL_ANNOTATION = "de.inetsoftware.jwebassembly.api.annotation.Partial";
|
||||
|
||||
/**
|
||||
* If the GC feature of WASM should be use or the GC of the JavaScript host. If true use the GC instructions of WASM.
|
||||
*/
|
||||
|
@ -104,15 +104,31 @@ public class ClassFileLoader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the class in the cache with the given instance.
|
||||
* Replace the class in the cache with the given instance to the loader cache.
|
||||
*
|
||||
* @param className
|
||||
* the name of the class to replace
|
||||
* @param classFile
|
||||
* the replasing ClassFile
|
||||
* the replacing ClassFile
|
||||
*/
|
||||
public void replace( String className, ClassFile classFile ) {
|
||||
void replace( String className, ClassFile classFile ) {
|
||||
classFile = new ClassFile( className, classFile );
|
||||
replace.put( className, classFile );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a partial class with the given instance to the loader cache.
|
||||
*
|
||||
* @param className
|
||||
* the name of the class to replace
|
||||
* @param partialClassFile
|
||||
* the partial ClassFile
|
||||
* @throws IOException
|
||||
* If any I/O error occur
|
||||
*/
|
||||
void partial( String className, ClassFile partialClassFile ) throws IOException {
|
||||
ClassFile classFile = get( className );
|
||||
replace.put( className, classFile );
|
||||
classFile.partial( partialClassFile );
|
||||
}
|
||||
}
|
||||
|
@ -172,6 +172,14 @@ public class ModuleGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
// check if this class extends another class with partial code
|
||||
if( (annotationValues = classFile.getAnnotation( JWebAssembly.PARTIAL_ANNOTATION )) != null ) {
|
||||
String signatureName = (String)annotationValues.get( "value" );
|
||||
if( signatureName != null ) {
|
||||
classFileLoader.partial( signatureName, classFile );
|
||||
}
|
||||
}
|
||||
|
||||
iterateMethods( classFile, m -> prepareMethod( m ) );
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user