33import com .googlecode .totallylazy .*;
44import com .googlecode .totallylazy .annotations .multimethod ;
55import javarepl .expressions .*;
6+ import javarepl .expressions .Method ;
7+ import javarepl .expressions .Type ;
68import javarepl .expressions .Value ;
79
810import javax .tools .DiagnosticCollector ;
1113import javax .tools .StandardJavaFileManager ;
1214import java .io .File ;
1315import java .io .FileNotFoundException ;
14- import java .lang .reflect .Constructor ;
15- import java .lang .reflect .Field ;
16+ import java .lang .reflect .*;
1617import java .net .URL ;
1718import java .util .regex .MatchResult ;
1819
@@ -97,8 +98,13 @@ private Import createImport(String expression) {
9798 }
9899
99100 private AssignmentWithType createAssignmentWithType (String expression ) {
100- MatchResult match = Patterns .assignmentWithTypeNamePattern .match (expression );
101- return new AssignmentWithType (expression , match .group (1 ), match .group (2 ), match .group (3 ));
101+ try {
102+ MatchResult match = Patterns .assignmentWithTypeNamePattern .match (expression );
103+ java .lang .reflect .Method declaredMethod = detectMethod (match .group (1 ) + " " + randomIdentifier ("method" ) + "(){}" );
104+ return new AssignmentWithType (expression , declaredMethod .getReturnType (), match .group (2 ), match .group (3 ));
105+ } catch (Exception e ) {
106+ throw new RuntimeException (e );
107+ }
102108 }
103109
104110 private Assignment createAssignmentExpression (String expression ) {
@@ -154,7 +160,7 @@ public final Option<Class> typeOfExpression(String expression) {
154160 if (evaluation .isRight ()) {
155161 Option <Result > result = evaluation .right ().result ();
156162 if (!result .isEmpty ()) {
157- expressionType = some ((Class ) result .get ().value (). getClass ());
163+ expressionType = some ((Class ) result .get ().type ());
158164 }
159165 }
160166
@@ -214,23 +220,25 @@ private Either<? extends Throwable, Evaluation> evaluate(Type expression) {
214220
215221 private Method createMethodExpression (String expression ) {
216222 try {
217- final String className = randomIdentifier ("Method" );
218- final File outputJavaFile = file (outputDirectory , className + ".java" );
219-
220- final String sources = renderMethodSignatureDetection (context , className , expression );
221- Files .write (sources .getBytes (), outputJavaFile );
223+ java .lang .reflect .Method declaredMethod = detectMethod (expression );
224+ return new Method (expression , declaredMethod .getReturnType (), declaredMethod .getName (), sequence (declaredMethod .getParameterTypes ()));
225+ } catch (Exception e ) {
226+ throw new RuntimeException (e );
227+ }
228+ }
222229
223- compile (outputJavaFile );
230+ private java .lang .reflect .Method detectMethod (String expression ) throws Exception {
231+ final String className = randomIdentifier ("Method" );
232+ final File outputJavaFile = file (outputDirectory , className + ".java" );
224233
225- Class <?> expressionClass = classLoader .loadClass (className );
234+ final String sources = renderMethodSignatureDetection (context , className , expression );
235+ Files .write (sources .getBytes (), outputJavaFile );
226236
227- java . lang . reflect . Method declaredMethod = expressionClass . getDeclaredMethods ()[ 0 ] ;
237+ compile ( outputJavaFile ) ;
228238
229- return new Method ( expression , declaredMethod . getReturnType (), declaredMethod . getName (), sequence ( declaredMethod . getParameterTypes ()) );
239+ Class <?> expressionClass = classLoader . loadClass ( className );
230240
231- } catch (Exception e ) {
232- throw new RuntimeException (e );
233- }
241+ return expressionClass .getDeclaredMethods ()[0 ];
234242 }
235243
236244 private Either <? extends Throwable , Evaluation > evaluateExpression (final Expression expression ) {
@@ -252,12 +260,13 @@ private Either<? extends Throwable, Evaluation> evaluateExpression(final Express
252260
253261 final Object expressionInstance = constructor .newInstance (newContext );
254262
255- Object resultObject = expressionClass .getMethod ("evaluate" ).invoke (expressionInstance );
263+ java .lang .reflect .Method method = expressionClass .getMethod ("evaluate" );
264+ Object resultObject = method .invoke (expressionInstance );
256265
257266 Sequence <Result > modifiedResults = modifiedResults (expressionInstance );
258267
259- if (resultObject != null ) {
260- Result result = Result .result (nextResultKeyFor (expression ), resultObject );
268+ if (resultObject != null || ! method . getReturnType (). equals ( void . class ) ) {
269+ Result result = Result .result (nextResultKeyFor (expression ), resultObject , typeFor ( expression ) );
261270 context = newContext .addExpression (expression ).addResults (modifiedResults .add (result )).lastSource (sources );
262271 return right (evaluation (expression , some (result )));
263272 } else {
@@ -294,6 +303,12 @@ private String nextResultKeyFor(Expression expression) {
294303 : expression .key ();
295304 }
296305
306+ private Option <Class <?>> typeFor (Expression expression ) {
307+ return (expression instanceof AssignmentWithType )
308+ ? Option .<Class <?>>some (((AssignmentWithType ) expression ).type ())
309+ : Option .<Class <?>>none ();
310+ }
311+
297312 private void compile (File file ) throws Exception {
298313 String classpath = sequence (System .getProperty ("java.class.path" )).join (sequence (classLoader .getURLs ()).map (toString )).toString (pathSeparator );
299314 JavaCompiler compiler = getSystemJavaCompiler ();
0 commit comments