forked from JavaTX/JavaCompilerCore
Klassendatei fuer FunN beim Methodaufruf wird erzeugt, wenn der Receiver
den Typ FunN besitzt. Die Loesung vom Duplicate Field Problem wird angepasst.
This commit is contained in:
parent
9ffc74467b
commit
73f412d22d
@ -67,7 +67,8 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
private ArrayList<String> tphsClass;
|
||||
|
||||
// stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,...
|
||||
// stores parameter, local vars and the next index on the local variable table,
|
||||
// which use for aload_i, astore_i,...
|
||||
HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
||||
// stores generics and their bounds of class
|
||||
HashMap<String, String> genericsAndBounds = new HashMap<>();
|
||||
@ -87,6 +88,8 @@ public class BytecodeGen implements ASTVisitor {
|
||||
private HashMap<String, SimplifyResult> simplifyResults = new HashMap<>();
|
||||
private List<HashMap<String, SimplifyResult>> simplifyResultsList = new ArrayList<>();
|
||||
|
||||
private final ArrayList<String> fieldNameSignature = new ArrayList<>();
|
||||
|
||||
public List<HashMap<String, SimplifyResult>> getSimplifyResultsList() {
|
||||
return simplifyResultsList;
|
||||
}
|
||||
@ -95,7 +98,8 @@ public class BytecodeGen implements ASTVisitor {
|
||||
this.simplifyResultsList = simplifyResultsList;
|
||||
}
|
||||
|
||||
public BytecodeGen(HashMap<String,byte[]> classFiles, List<ResultSet> listOfResultSets,SourceFile sf ,String path) {
|
||||
public BytecodeGen(HashMap<String, byte[]> classFiles, List<ResultSet> listOfResultSets, SourceFile sf,
|
||||
String path) {
|
||||
this.classFiles = classFiles;
|
||||
this.listOfResultSets = listOfResultSets;
|
||||
this.sf = sf;
|
||||
@ -114,8 +118,8 @@ public class BytecodeGen implements ASTVisitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the bytecode of the class that was build with the classWriter {@link #cw}
|
||||
* with the class name in the map {@link #classFiles}
|
||||
* Associates the bytecode of the class that was build with the classWriter
|
||||
* {@link #cw} with the class name in the map {@link #classFiles}
|
||||
*
|
||||
* @param name name of the class with which the the bytecode is to be associated
|
||||
*/
|
||||
@ -129,7 +133,6 @@ public class BytecodeGen implements ASTVisitor {
|
||||
return classFiles;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(ClassOrInterface classOrInterface) {
|
||||
|
||||
@ -139,7 +142,8 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
isInterface = (classOrInterface.getModifiers() & 512) == 512;
|
||||
|
||||
int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER;
|
||||
int acc = isInterface ? classOrInterface.getModifiers() + Opcodes.ACC_ABSTRACT
|
||||
: classOrInterface.getModifiers() + Opcodes.ACC_SUPER;
|
||||
|
||||
fieldInitializations = classOrInterface.getfieldInitializations();
|
||||
|
||||
@ -164,14 +168,15 @@ public class BytecodeGen implements ASTVisitor {
|
||||
}
|
||||
|
||||
String sig = null;
|
||||
/* if class has generics then creates signature
|
||||
* Signature looks like:
|
||||
/*
|
||||
* if class has generics then creates signature Signature looks like:
|
||||
* <E:Ljava/...>Superclass
|
||||
*/
|
||||
if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() ||
|
||||
classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
|
||||
if (classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty()
|
||||
|| classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
|
||||
|| !tphsClass.isEmpty()) {
|
||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraintsClass(tphExtractor,tphsClass);
|
||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify
|
||||
.simplifyConstraintsClass(tphExtractor, tphsClass);
|
||||
ArrayList<TPHConstraint> consClass = new ArrayList<>();
|
||||
for (TPHConstraint cons : constraints.keySet()) {
|
||||
String right = null;
|
||||
@ -205,13 +210,14 @@ public class BytecodeGen implements ASTVisitor {
|
||||
SimplifyResult sRes = new SimplifyResult(consClass, tphsClass, new HashMap<>());
|
||||
simplifyResults.put(className, sRes);
|
||||
|
||||
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass, consClass);
|
||||
Signature signature = new Signature(classOrInterface, genericsAndBounds, commonPairs, tphsClass,
|
||||
consClass);
|
||||
sig = signature.toString();
|
||||
System.out.println("Signature: => " + sig);
|
||||
}
|
||||
|
||||
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString()
|
||||
, sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
||||
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString(), sig,
|
||||
classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
||||
|
||||
isVisited = true;
|
||||
}
|
||||
@ -307,15 +313,15 @@ public class BytecodeGen implements ASTVisitor {
|
||||
for (String paramName : methodParamsAndTypes.keySet()) {
|
||||
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
|
||||
System.out.println(typeOfParam);
|
||||
if(genericsAndBounds.containsKey(typeOfParam) ||typeOfParam.contains("$")
|
||||
|| typeOfParam.contains("<")) {
|
||||
if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("$") || typeOfParam.contains("<")) {
|
||||
hasGen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String sig = null;
|
||||
if (hasGen) {
|
||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,tphsClass);
|
||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,
|
||||
tphsClass);
|
||||
Signature signature = new Signature(field, genericsAndBounds, methodParamsAndTypes, resultSet, constraints);
|
||||
sig = signature.toString();
|
||||
}
|
||||
@ -334,7 +340,8 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, field, mv, paramsAndLocals, cw,
|
||||
genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, block, constructorPos);
|
||||
if(!field.getParameterList().iterator().hasNext() && !(field.block.statements.get(field.block.statements.size()-1) instanceof ReturnVoid)) {
|
||||
if (!field.getParameterList().iterator().hasNext()
|
||||
&& !(field.block.statements.get(field.block.statements.size() - 1) instanceof ReturnVoid)) {
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
}
|
||||
mv.visitMaxs(0, 0);
|
||||
@ -343,7 +350,8 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(Method method) {
|
||||
// TODO: check if the method is static => if static then the first param will be stored in pos 0
|
||||
// TODO: check if the method is static => if static then the first param will be
|
||||
// stored in pos 0
|
||||
// else it will be stored in pos 1 and this will be stored in pos 0
|
||||
String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
// String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||
@ -371,36 +379,45 @@ public class BytecodeGen implements ASTVisitor {
|
||||
System.out.println(acc);
|
||||
|
||||
/* Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist */
|
||||
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ") ||
|
||||
resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()).contains("<");
|
||||
/*Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature, wenn nicht,
|
||||
* prüfe, ob einer der Parameter Typ-Variable als Typ hat*/
|
||||
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ")
|
||||
|| resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature())
|
||||
.contains("<");
|
||||
/*
|
||||
* Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature,
|
||||
* wenn nicht, prüfe, ob einer der Parameter Typ-Variable als Typ hat
|
||||
*/
|
||||
if (!hasGenInParameterList) {
|
||||
for (String paramName : methodParamsAndTypes.keySet()) {
|
||||
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
|
||||
String sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
|
||||
if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.contains("TPH ")||sigOfParam.contains("<")) {
|
||||
if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("TPH ")
|
||||
|| sigOfParam.contains("<")) {
|
||||
hasGenInParameterList = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO: Test if the return-type or any of the parameter is a parameterized type. (VP)
|
||||
// TODO: Test if the return-type or any of the parameter is a parameterized
|
||||
// type. (VP)
|
||||
// then create the descriptor with the new syntax.
|
||||
|
||||
String sig = null;
|
||||
/* method.getGenerics: <....> RT method(..)
|
||||
* */
|
||||
/*
|
||||
* method.getGenerics: <....> RT method(..)
|
||||
*/
|
||||
boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList;
|
||||
/* if method has generics or return type is TPH, create signature */
|
||||
// zwite operand muss weggelassen werden
|
||||
if(hasGen||resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()).equals("TPH")) {
|
||||
if (hasGen || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString())
|
||||
.equals("TPH")) {
|
||||
System.out.println("ALL CONST: " + tphExtractor.allCons.size());
|
||||
tphExtractor.allCons.forEach(c -> System.out.println(c.toString()));
|
||||
System.out.println("----------------");
|
||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name, tphExtractor, tphsClass);
|
||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name,
|
||||
tphExtractor, tphsClass);
|
||||
// ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons);
|
||||
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
||||
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,
|
||||
methodParamsAndTypes, resultSet, constraints);
|
||||
sig = signature.toString();
|
||||
if (simplifyResults.containsKey(className)) {
|
||||
simplifyResults.get(className).getMethodsConstraints().put(methParamTypes, constraints);
|
||||
@ -484,7 +501,8 @@ public class BytecodeGen implements ASTVisitor {
|
||||
public void visit(FieldVar fieldVar) {
|
||||
System.out.println("In FieldVar ---");
|
||||
// cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString());
|
||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L"+fieldVar.getType()+";", null, null);
|
||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L" + fieldVar.getType() + ";",
|
||||
null, null);
|
||||
fv.visitEnd();
|
||||
}
|
||||
|
||||
@ -505,15 +523,17 @@ public class BytecodeGen implements ASTVisitor {
|
||||
sig += ";";
|
||||
}
|
||||
String nameAndDesc = field.getName() + "%%" + des;
|
||||
|
||||
if(fieldNameAndParamsT.contains(nameAndDesc))
|
||||
String nameAndSig = field.getName() + "%%" + sig;
|
||||
if (fieldNameAndParamsT.contains(nameAndDesc)) {
|
||||
if (fieldNameSignature.contains(nameAndSig)) {
|
||||
return;
|
||||
}
|
||||
throw new BytecodeGeneratorError("Bytecode generation aborted due to duplicate field name&signature");
|
||||
|
||||
}
|
||||
fieldNameAndParamsT.add(nameAndDesc);
|
||||
fieldNameSignature.add(nameAndSig);
|
||||
|
||||
cw.visitField(field.modifier, field.getName(),
|
||||
des, sig,
|
||||
null);
|
||||
cw.visitField(field.modifier, field.getName(), des, sig, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -694,5 +714,4 @@ public class BytecodeGen implements ASTVisitor {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -678,7 +678,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
}
|
||||
methSig.visitReturnType().visitTypeVariable("R");
|
||||
// ")"+lam.getReturn.getBounds
|
||||
Signature sig = new Signature(lambdaExpression, numberOfParams);
|
||||
Signature sig = new Signature(numberOfParams);
|
||||
String name = "Fun" + numberOfParams + "$$";
|
||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
||||
Type.getInternalName(Object.class), null);
|
||||
@ -778,9 +778,9 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
|
||||
String mDesc = "";
|
||||
|
||||
MethodCallHelper helper = new MethodCallHelper(methodCall, sf, resultSet);
|
||||
MethodCallHelper helper = new MethodCallHelper(methodCall, sf, resultSet, path);
|
||||
|
||||
boolean isCreated = false;
|
||||
boolean toCreate = false;
|
||||
|
||||
ClassLoader cLoader = ClassLoader.getSystemClassLoader();
|
||||
// This will be used if the class is not standard class (not in API)
|
||||
@ -799,7 +799,6 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
|
||||
} catch (Exception e) {
|
||||
String superClass = "";
|
||||
// TODO: Test SubMatrix.jav
|
||||
while(true) {
|
||||
try {
|
||||
superClass = helper.getSuperClass(receiverName);
|
||||
@ -833,14 +832,17 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
}
|
||||
|
||||
if(methodRefl == null) {
|
||||
isCreated = !receiverName.equals(className) && helper.isInCurrPkg(clazz);
|
||||
if(isCreated) {
|
||||
toCreate = !receiverName.equals(className) && helper.isInCurrPkg(clazz);
|
||||
if(toCreate) {
|
||||
try {
|
||||
mDesc = helper.getDesc(clazz);
|
||||
} catch (NotInCurrentPackageException | NotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if(!helper.isInCurrPkg(clazz)){
|
||||
if(clazz.contains("$$")) {
|
||||
mDesc = helper.generateBCForFunN();
|
||||
}else {
|
||||
try {
|
||||
cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)});
|
||||
java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods();
|
||||
@ -854,6 +856,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -80,12 +80,12 @@ public class Signature {
|
||||
createSignatureForConsOrMethod(this.method,false);
|
||||
}
|
||||
|
||||
public Signature(LambdaExpression lambdaExpression,int numberOfParams) {
|
||||
public Signature(int numberOfParams) {
|
||||
sw = new SignatureWriter();
|
||||
createSignatureForFunN(lambdaExpression, numberOfParams);
|
||||
createSignatureForFunN(numberOfParams);
|
||||
}
|
||||
|
||||
private void createSignatureForFunN(LambdaExpression lambdaExpression, int numberOfParams) {
|
||||
private void createSignatureForFunN(int numberOfParams) {
|
||||
|
||||
// sw.visitClassBound().visitEnd();
|
||||
for(int i = 0;i<numberOfParams;i++) {
|
||||
|
@ -3,6 +3,10 @@
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.utilities;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@ -11,11 +15,17 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
import org.objectweb.asm.signature.SignatureWriter;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
@ -23,6 +33,8 @@ import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
@ -38,16 +50,19 @@ public class MethodCallHelper {
|
||||
private MethodCall methCall;
|
||||
private SourceFile sourceFile;
|
||||
private ResultSet resultSet;
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* @param methCall
|
||||
* @param sourceFile
|
||||
* @param resultSet
|
||||
* @param path TODO
|
||||
*/
|
||||
public MethodCallHelper(MethodCall methCall, SourceFile sourceFile, ResultSet resultSet) {
|
||||
public MethodCallHelper(MethodCall methCall, SourceFile sourceFile, ResultSet resultSet, String path) {
|
||||
this.methCall = methCall;
|
||||
this.sourceFile = sourceFile;
|
||||
this.resultSet = resultSet;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
@ -189,19 +204,52 @@ public class MethodCallHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private String createDesc(Method m) {
|
||||
String desc = "(";
|
||||
for (FormalParameter fp : m.getParameterList()) {
|
||||
String typeName = getResolvedType(fp.getType());
|
||||
RefTypeOrTPHOrWildcardOrGeneric type = resultSet.resolveType(fp.getType()).resolvedType;
|
||||
if (type instanceof TypePlaceholder) {
|
||||
desc += "L" + Type.getInternalName(Object.class) + ";";
|
||||
} else if (type instanceof GenericRefType) {
|
||||
GenericRefType grt = (GenericRefType) type;
|
||||
public String generateBCForFunN() {
|
||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
|
||||
SignatureWriter methSig = new SignatureWriter();
|
||||
|
||||
int numberOfParams = 0;
|
||||
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
||||
Iterator<Expression> itr1 = methCall.arglist.getArguments().iterator();
|
||||
String methDesc = "(";
|
||||
while(itr1.hasNext()) {
|
||||
numberOfParams++;
|
||||
// getBounds
|
||||
paramVisitor.visitTypeVariable("T" + numberOfParams);
|
||||
methDesc += "L" + Type.getInternalName(Object.class) + ";";
|
||||
itr1.next();
|
||||
}
|
||||
methDesc += ")L" + Type.getInternalName(Object.class) + ";";
|
||||
|
||||
methSig.visitReturnType().visitTypeVariable("R");
|
||||
// ")"+lam.getReturn.getBounds
|
||||
Signature sig = new Signature(numberOfParams);
|
||||
String name = "Fun" + numberOfParams + "$$";
|
||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
||||
Type.getInternalName(Object.class), null);
|
||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
||||
methSig.toString(), null);
|
||||
mvApply.visitEnd();
|
||||
writeClassFile(classWriter.toByteArray(), name);
|
||||
return methDesc;
|
||||
}
|
||||
return null;
|
||||
|
||||
private void writeClassFile(byte[] bytecode, String name) {
|
||||
FileOutputStream output;
|
||||
try {
|
||||
System.out.println("generating " + name + ".class file...");
|
||||
output = new FileOutputStream(
|
||||
new File(path + name + ".class"));
|
||||
output.write(bytecode);
|
||||
output.close();
|
||||
System.out.println(name + ".class file generated");
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ public class MethodFromMethodCall {
|
||||
this.genericsAndBounds = genericsAndBounds;
|
||||
}
|
||||
|
||||
|
||||
public ArgumentList getArgList() {
|
||||
return argList;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user