102 new AbstractMethod("int", stdMethodName);
103
104 /**
105 * Returns a class which has a static method with the same name as
106 * 'method', whose body creates an new instance of 'specimen' and invokes
107 * 'method' upon it via an invokevirtual instruction with 'args' as
108 * function call parameters.
109 *
110 * 'returns' is a dummy return value that need only match 'methods'
111 * return type (it is only used in the dummy class when compiling IV).
112 */
113 private Class invokeVirtualHarness(
114 Class specimen, ConcreteMethod method,
115 String returns, String ... args) {
116 Method cm = new ConcreteMethod(
117 method.getReturnType(), method.getName(),
118 "return " + returns + ";", method.getElements());
119 Class stub = new Class(specimen.getName(), cm);
120
121 String params =
122 Arrays.asList(args).stream().collect(Collectors.toStringJoiner(", ")).toString();
123
124 ConcreteMethod sm = new ConcreteMethod(
125 method.getReturnType(), method.getName(),
126 String.format("return (new %s()).%s(%s);",
127 specimen.getName(), method.getName(), params),
128 new AccessFlag("public"), new AccessFlag("static"));
129
130 Class iv = new Class("IV_" + specimen.getName(), sm);
131
132 iv.addCompilationDependency(stub);
133 iv.addCompilationDependency(cm);
134
135 return iv;
136 }
137
138 /**
139 * Returns a class which has a static method with the same name as
140 * 'method', whose body creates an new instance of 'specimen', casts it
141 * to 'iface' (including the type parameters) and invokes
142 * 'method' upon it via an invokeinterface instruction with 'args' as
143 * function call parameters.
144 */
145 private Class invokeInterfaceHarness(Class specimen, Extends iface,
146 AbstractMethod method, String ... args) {
147 Interface istub = new Interface(
148 iface.getType().getName(), iface.getType().getAccessFlags(),
149 iface.getType().getParameters(),
150 null, Arrays.asList((Method)method));
151 Class cstub = new Class(specimen.getName());
152
153 String params = Arrays.asList(args).stream().collect(Collectors.toStringJoiner(", ")).toString();
154
155 ConcreteMethod sm = new ConcreteMethod(
156 "int", SourceModel.stdMethodName,
157 String.format("return ((%s)(new %s())).%s(%s);", iface.toString(),
158 specimen.getName(), method.getName(), params),
159 new AccessFlag("public"), new AccessFlag("static"));
160 sm.suppressWarnings();
161
162 Class ii = new Class("II_" + specimen.getName() + "_" +
163 iface.getType().getName(), sm);
164 ii.addCompilationDependency(istub);
165 ii.addCompilationDependency(cstub);
166 ii.addCompilationDependency(method);
167 return ii;
168 }
169
170
171 /**
172 * Uses 'loader' to load class 'clzz', and calls the static method
173 * 'method'. If the return value does not equal 'value' (or if an
|
102 new AbstractMethod("int", stdMethodName);
103
104 /**
105 * Returns a class which has a static method with the same name as
106 * 'method', whose body creates an new instance of 'specimen' and invokes
107 * 'method' upon it via an invokevirtual instruction with 'args' as
108 * function call parameters.
109 *
110 * 'returns' is a dummy return value that need only match 'methods'
111 * return type (it is only used in the dummy class when compiling IV).
112 */
113 private Class invokeVirtualHarness(
114 Class specimen, ConcreteMethod method,
115 String returns, String ... args) {
116 Method cm = new ConcreteMethod(
117 method.getReturnType(), method.getName(),
118 "return " + returns + ";", method.getElements());
119 Class stub = new Class(specimen.getName(), cm);
120
121 String params =
122 Arrays.asList(args).stream().collect(Collectors.joining(", ")).toString();
123
124 ConcreteMethod sm = new ConcreteMethod(
125 method.getReturnType(), method.getName(),
126 String.format("return (new %s()).%s(%s);",
127 specimen.getName(), method.getName(), params),
128 new AccessFlag("public"), new AccessFlag("static"));
129
130 Class iv = new Class("IV_" + specimen.getName(), sm);
131
132 iv.addCompilationDependency(stub);
133 iv.addCompilationDependency(cm);
134
135 return iv;
136 }
137
138 /**
139 * Returns a class which has a static method with the same name as
140 * 'method', whose body creates an new instance of 'specimen', casts it
141 * to 'iface' (including the type parameters) and invokes
142 * 'method' upon it via an invokeinterface instruction with 'args' as
143 * function call parameters.
144 */
145 private Class invokeInterfaceHarness(Class specimen, Extends iface,
146 AbstractMethod method, String ... args) {
147 Interface istub = new Interface(
148 iface.getType().getName(), iface.getType().getAccessFlags(),
149 iface.getType().getParameters(),
150 null, Arrays.asList((Method)method));
151 Class cstub = new Class(specimen.getName());
152
153 String params = Arrays.asList(args).stream().collect(Collectors.joining(", ")).toString();
154
155 ConcreteMethod sm = new ConcreteMethod(
156 "int", SourceModel.stdMethodName,
157 String.format("return ((%s)(new %s())).%s(%s);", iface.toString(),
158 specimen.getName(), method.getName(), params),
159 new AccessFlag("public"), new AccessFlag("static"));
160 sm.suppressWarnings();
161
162 Class ii = new Class("II_" + specimen.getName() + "_" +
163 iface.getType().getName(), sm);
164 ii.addCompilationDependency(istub);
165 ii.addCompilationDependency(cstub);
166 ii.addCompilationDependency(method);
167 return ii;
168 }
169
170
171 /**
172 * Uses 'loader' to load class 'clzz', and calls the static method
173 * 'method'. If the return value does not equal 'value' (or if an
|