@ -134,63 +134,74 @@ public class ClassWriter {
DecompilerContext . getLogger ( ) . startWriteClass ( node . simpleName ) ;
DecompilerContext . getLogger ( ) . startWriteClass ( node . simpleName ) ;
// lambda method
if ( node . lambda_information . is_method_reference ) {
StructMethod mt = cl . getMethod ( node . lambda_information . content_method_key ) ;
MethodWrapper meth = wrapper . getMethodWrapper ( mt . getName ( ) , mt . getDescriptor ( ) ) ;
MethodDescriptor md_content = MethodDescriptor . parseDescriptor ( node . lambda_information . content_method_descriptor ) ;
writer . write ( ExprProcessor . getCastTypeName ( new VarType ( node . lambda_information . content_class_name , false ) ) ) ;
MethodDescriptor md_lambda = MethodDescriptor . parseDescriptor ( node . lambda_information . method_descriptor ) ;
writer . write ( "::" ) ;
writer . write ( node . lambda_information . content_method_name ) ;
if ( ! lambda_to_anonymous ) { // lambda parameters '() ->'
writer . flush ( ) ;
StringBuilder buff = new StringBuilder ( "(" ) ;
} else {
boolean firstpar = true ;
// lambda method
int index = 1 ;
StructMethod mt = cl . getMethod ( node . lambda_information . content_method_key ) ;
MethodWrapper meth = wrapper . getMethodWrapper ( mt . getName ( ) , mt . getDescriptor ( ) ) ;
int start_index = md_content . params . length - md_lambda . params . length ;
MethodDescriptor md_content = MethodDescriptor . parseDescriptor ( node . lambda_information . content_method_descriptor ) ;
MethodDescriptor md_lambda = MethodDescriptor . parseDescriptor ( node . lambda_information . method_descriptor ) ;
for ( int i = 0 ; i < md_content . params . length ; i + + ) {
if ( ! lambda_to_anonymous ) { // lambda parameters '() ->'
if ( i > = start_index ) {
StringBuilder buff = new StringBuilder ( "(" ) ;
if ( ! firstpar ) {
boolean firstpar = true ;
buff . append ( ", " ) ;
int index = 1 ;
}
String parname = meth . varproc . getVarName ( new VarVersionPaar ( index , 0 ) ) ;
int start_index = md_content . params . length - md_lambda . params . length ;
buff . append ( parname = = null ? "param" + index : parname ) ; // null iff decompiled with errors
firstpar = false ;
for ( int i = 0 ; i < md_content . params . length ; i + + ) {
}
index + = md_content . params [ i ] . stack_size ;
if ( i > = start_index ) {
}
buff . append ( ") ->" ) ;
writer . write ( buff . toString ( ) ) ;
if ( ! firstpar ) {
}
buff . append ( ", " ) ;
}
StringWriter strwriter = new StringWriter ( ) ;
String parname = meth . varproc . getVarName ( new VarVersionPaar ( index , 0 ) ) ;
BufferedWriter bufstrwriter = new BufferedWriter ( strwriter ) ;
buff . append ( parname = = null ? "param" + index : parname ) ; // null iff decompiled with errors
if ( lambda_to_anonymous ) {
firstpar = false ;
methodLambdaToJava ( node , node_content , mt , bufstrwriter , indent + 1 , false ) ;
}
} else {
methodLambdaToJava ( node , node_content , mt , bufstrwriter , indent , true ) ;
}
bufstrwriter . flush ( ) ;
index + = md_content . params [ i ] . stack_size ;
}
buff . append ( ") ->" ) ;
// closing up class definition
writer . write ( buff . toString ( ) ) ;
writer . write ( " {" ) ;
}
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
writer . write ( strwriter . toString ( ) ) ;
StringWriter strwriter = new StringWriter ( ) ;
BufferedWriter bufstrwriter = new BufferedWriter ( strwriter ) ;
writer . write ( InterpreterUtil . getIndentString ( indent ) ) ;
if ( lambda_to_anonymous ) {
writer . write ( "}" ) ;
methodLambdaToJava ( node , node_content , mt , bufstrwriter , indent + 1 , false ) ;
writer . flush ( ) ;
} else {
methodLambdaToJava ( node , node_content , mt , bufstrwriter , indent , true ) ;
}
bufstrwriter . flush ( ) ;
// closing up class definition
writer . write ( " {" ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
writer . write ( strwriter . toString ( ) ) ;
writer . write ( InterpreterUtil . getIndentString ( indent ) ) ;
writer . write ( "}" ) ;
writer . flush ( ) ;
}
DecompilerContext . setProperty ( DecompilerContext . CURRENT_CLASSNODE , nodeold ) ;
DecompilerContext . setProperty ( DecompilerContext . CURRENT_CLASSNODE , nodeold ) ;
@ -345,18 +356,18 @@ public class ClassWriter {
}
}
}
}
if ( isDeprecated ) {
if ( isDeprecated ) {
writer . write ( indstr ) ;
writer . write ( indstr ) ;
writer . write ( "/** @deprecated */" ) ;
writer . write ( "/** @deprecated */" ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
}
}
// class annotations
// class annotations
List < AnnotationExprent > lstAnn = getAllAnnotations ( cl . getAttributes ( ) ) ;
List < AnnotationExprent > lstAnn = getAllAnnotations ( cl . getAttributes ( ) ) ;
for ( AnnotationExprent annexpr : lstAnn ) {
for ( AnnotationExprent annexpr : lstAnn ) {
writer . write ( annexpr . toJava ( indent ) ) ;
writer . write ( annexpr . toJava ( indent ) ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
}
}
boolean isSynthetic = ( flags & CodeConstants . ACC_SYNTHETIC ) ! = 0 | | cl . getAttributes ( ) . containsKey ( "Synthetic" ) ;
boolean isSynthetic = ( flags & CodeConstants . ACC_SYNTHETIC ) ! = 0 | | cl . getAttributes ( ) . containsKey ( "Synthetic" ) ;
@ -481,18 +492,18 @@ public class ClassWriter {
boolean isDeprecated = fd . getAttributes ( ) . containsKey ( "Deprecated" ) ;
boolean isDeprecated = fd . getAttributes ( ) . containsKey ( "Deprecated" ) ;
if ( isDeprecated ) {
if ( isDeprecated ) {
writer . write ( indstr ) ;
writer . write ( indstr ) ;
writer . write ( "/** @deprecated */" ) ;
writer . write ( "/** @deprecated */" ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
}
}
// field annotations
// field annotations
List < AnnotationExprent > lstAnn = getAllAnnotations ( fd . getAttributes ( ) ) ;
List < AnnotationExprent > lstAnn = getAllAnnotations ( fd . getAttributes ( ) ) ;
for ( AnnotationExprent annexpr : lstAnn ) {
for ( AnnotationExprent annexpr : lstAnn ) {
writer . write ( annexpr . toJava ( indent ) ) ;
writer . write ( annexpr . toJava ( indent ) ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
}
}
boolean isSynthetic = ( flags & CodeConstants . ACC_SYNTHETIC ) ! = 0 | | fd . getAttributes ( ) . containsKey ( "Synthetic" ) ;
boolean isSynthetic = ( flags & CodeConstants . ACC_SYNTHETIC ) ! = 0 | | fd . getAttributes ( ) . containsKey ( "Synthetic" ) ;
boolean isEnum = DecompilerContext . getOption ( IFernflowerPreferences . DECOMPILE_ENUM ) & & ( flags & CodeConstants . ACC_ENUM ) ! = 0 ;
boolean isEnum = DecompilerContext . getOption ( IFernflowerPreferences . DECOMPILE_ENUM ) & & ( flags & CodeConstants . ACC_ENUM ) ! = 0 ;
@ -674,7 +685,7 @@ public class ClassWriter {
boolean isInterface = ( cl . access_flags & CodeConstants . ACC_INTERFACE ) ! = 0 ;
boolean isInterface = ( cl . access_flags & CodeConstants . ACC_INTERFACE ) ! = 0 ;
boolean isAnnotation = ( cl . access_flags & CodeConstants . ACC_ANNOTATION ) ! = 0 ;
boolean isAnnotation = ( cl . access_flags & CodeConstants . ACC_ANNOTATION ) ! = 0 ;
boolean isEnum = ( cl . access_flags & CodeConstants . ACC_ENUM ) ! = 0 & & DecompilerContext . getOption ( IFernflowerPreferences . DECOMPILE_ENUM ) ;
boolean isEnum = ( cl . access_flags & CodeConstants . ACC_ENUM ) ! = 0 & & DecompilerContext . getOption ( IFernflowerPreferences . DECOMPILE_ENUM ) ;
boolean isDeprecated = mt . getAttributes ( ) . containsKey ( "Deprecated" ) ;
boolean isDeprecated = mt . getAttributes ( ) . containsKey ( "Deprecated" ) ;
String indstr = InterpreterUtil . getIndentString ( indent ) ;
String indstr = InterpreterUtil . getIndentString ( indent ) ;
@ -705,18 +716,18 @@ public class ClassWriter {
}
}
}
}
if ( isDeprecated ) {
if ( isDeprecated ) {
writer . write ( indstr ) ;
writer . write ( indstr ) ;
writer . write ( "/** @deprecated */" ) ;
writer . write ( "/** @deprecated */" ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
writer . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
}
}
// method annotations
// method annotations
List < AnnotationExprent > lstAnn = getAllAnnotations ( mt . getAttributes ( ) ) ;
List < AnnotationExprent > lstAnn = getAllAnnotations ( mt . getAttributes ( ) ) ;
for ( AnnotationExprent annexpr : lstAnn ) {
for ( AnnotationExprent annexpr : lstAnn ) {
bufstrwriter . write ( annexpr . toJava ( indent ) ) ;
bufstrwriter . write ( annexpr . toJava ( indent ) ) ;
bufstrwriter . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
bufstrwriter . write ( DecompilerContext . getNewLineSeparator ( ) ) ;
}
}
boolean isSynthetic = ( flags & CodeConstants . ACC_SYNTHETIC ) ! = 0 | | mt . getAttributes ( ) . containsKey ( "Synthetic" ) ;
boolean isSynthetic = ( flags & CodeConstants . ACC_SYNTHETIC ) ! = 0 | | mt . getAttributes ( ) . containsKey ( "Synthetic" ) ;
boolean isBridge = ( flags & CodeConstants . ACC_BRIDGE ) ! = 0 ;
boolean isBridge = ( flags & CodeConstants . ACC_BRIDGE ) ! = 0 ;
@ -747,19 +758,19 @@ public class ClassWriter {
bufstrwriter . write ( "default " ) ;
bufstrwriter . write ( "default " ) ;
}
}
String name = mt . getName ( ) ;
String name = mt . getName ( ) ;
if ( "<init>" . equals ( name ) ) {
if ( "<init>" . equals ( name ) ) {
if ( node . type = = ClassNode . CLASS_ANONYMOUS ) {
if ( node . type = = ClassNode . CLASS_ANONYMOUS ) {
name = "" ;
name = "" ;
dinit = true ;
dinit = true ;
} else {
} else {
name = node . simpleName ;
name = node . simpleName ;
init = true ;
init = true ;
}
}
} else if ( "<clinit>" . equals ( name ) ) {
} else if ( "<clinit>" . equals ( name ) ) {
name = "" ;
name = "" ;
clinit = true ;
clinit = true ;
}
}
GenericMethodDescriptor descriptor = null ;
GenericMethodDescriptor descriptor = null ;
if ( DecompilerContext . getOption ( IFernflowerPreferences . DECOMPILE_GENERIC_SIGNATURES ) ) {
if ( DecompilerContext . getOption ( IFernflowerPreferences . DECOMPILE_GENERIC_SIGNATURES ) ) {
@ -793,14 +804,14 @@ public class ClassWriter {
bufstrwriter . write ( descriptor . fparameters . get ( i ) ) ;
bufstrwriter . write ( descriptor . fparameters . get ( i ) ) ;
List < GenericType > lstBounds = descriptor . fbounds . get ( i ) ;
List < GenericType > lstBounds = descriptor . fbounds . get ( i ) ;
if ( lstBounds . size ( ) > 1 | | ! "java/lang/Object" . equals ( lstBounds . get ( 0 ) . value ) ) {
if ( lstBounds . size ( ) > 1 | | ! "java/lang/Object" . equals ( lstBounds . get ( 0 ) . value ) ) {
bufstrwriter . write ( " extends " ) ;
bufstrwriter . write ( " extends " ) ;
bufstrwriter . write ( GenericMain . getGenericCastTypeName ( lstBounds . get ( 0 ) ) ) ;
bufstrwriter . write ( GenericMain . getGenericCastTypeName ( lstBounds . get ( 0 ) ) ) ;
for ( int j = 1 ; j < lstBounds . size ( ) ; j + + ) {
for ( int j = 1 ; j < lstBounds . size ( ) ; j + + ) {
bufstrwriter . write ( " & " + GenericMain . getGenericCastTypeName ( lstBounds . get ( j ) ) ) ;
bufstrwriter . write ( " & " + GenericMain . getGenericCastTypeName ( lstBounds . get ( j ) ) ) ;
}
}
}
}
}
}
bufstrwriter . write ( "> " ) ;
bufstrwriter . write ( "> " ) ;
}
}
@ -831,11 +842,11 @@ public class ClassWriter {
}
}
boolean firstpar = true ;
boolean firstpar = true ;
int index = isEnum & & init ? 3 : thisvar ? 1 : 0 ;
int index = isEnum & & init ? 3 : thisvar ? 1 : 0 ;
int start = isEnum & & init & & descriptor = = null ? 2 : 0 ;
int start = isEnum & & init & & descriptor = = null ? 2 : 0 ;
int params = descriptor = = null ? md . params . length : descriptor . params . size ( ) ;
int params = descriptor = = null ? md . params . length : descriptor . params . size ( ) ;
for ( int i = start ; i < params ; i + + ) {
for ( int i = start ; i < params ; i + + ) {
if ( signFields = = null | | signFields . get ( i ) = = null ) {
if ( signFields = = null | | signFields . get ( i ) = = null ) {
if ( ! firstpar ) {
if ( ! firstpar ) {
bufstrwriter . write ( ", " ) ;
bufstrwriter . write ( ", " ) ;