mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +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.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -48,9 +50,9 @@ public class ClassFile {
|
|||||||
|
|
||||||
private final ConstantClass[] interfaces;
|
private final ConstantClass[] interfaces;
|
||||||
|
|
||||||
private final FieldInfo[] fields;
|
private FieldInfo[] fields;
|
||||||
|
|
||||||
private final MethodInfo[] methods;
|
private MethodInfo[] methods;
|
||||||
|
|
||||||
private final Attributes attributes;
|
private final Attributes attributes;
|
||||||
|
|
||||||
@ -136,16 +138,27 @@ public class ClassFile {
|
|||||||
methods = classFile.methods;
|
methods = classFile.methods;
|
||||||
attributes = classFile.attributes;
|
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
|
// patch constant pool
|
||||||
String origClassName = classFile.thisClass.getName();
|
|
||||||
for( int i = 0; i < constantPool.size(); i++ ) {
|
for( int i = 0; i < constantPool.size(); i++ ) {
|
||||||
Object obj = constantPool.get( i );
|
Object obj = constantPool.get( i );
|
||||||
if( obj instanceof ConstantClass ) {
|
if( obj instanceof ConstantClass ) {
|
||||||
if( ((ConstantClass)obj).getName().equals( origClassName ) ) {
|
if( ((ConstantClass)obj).getName().equals( origClassName ) ) {
|
||||||
constantPool.set( i, thisClass );
|
constantPool.set( i, thisClass );
|
||||||
}
|
}
|
||||||
} else if( obj instanceof ConstantFieldRef ) {
|
} else if( obj instanceof ConstantRef ) {
|
||||||
ConstantFieldRef ref = (ConstantFieldRef)obj;
|
ConstantRef ref = (ConstantRef)obj;
|
||||||
if( ref.getClassName().equals( origClassName ) ) {
|
if( ref.getClassName().equals( origClassName ) ) {
|
||||||
ConstantNameAndType nameAndType = new ConstantNameAndType( ref.getName(), ref.getType() );
|
ConstantNameAndType nameAndType = new ConstantNameAndType( ref.getName(), ref.getType() );
|
||||||
constantPool.set( i, new ConstantFieldRef( thisClass, nameAndType ) );
|
constantPool.set( i, new ConstantFieldRef( thisClass, nameAndType ) );
|
||||||
@ -301,4 +314,31 @@ public class ClassFile {
|
|||||||
public static enum Type {
|
public static enum Type {
|
||||||
Class, Interface, Enum;
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with 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.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import de.inetsoftware.classparser.Attributes.AttributeInfo;
|
import de.inetsoftware.classparser.Attributes.AttributeInfo;
|
||||||
@ -200,4 +201,14 @@ public class MethodInfo implements Member {
|
|||||||
public ConstantPool getConstantPool() {
|
public ConstantPool getConstantPool() {
|
||||||
return constantPool;
|
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";
|
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.
|
* 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
|
* @param className
|
||||||
* the name of the class to replace
|
* the name of the class to replace
|
||||||
* @param classFile
|
* @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 );
|
classFile = new ClassFile( className, classFile );
|
||||||
replace.put( 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 ) );
|
iterateMethods( classFile, m -> prepareMethod( m ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user