Community
Participate
Working Groups
Code Example: package workbench; import java.util.Arrays; import java.util.function.Predicate; import java.util.stream.Collectors; import com.google.common.base.Predicates; public class ScopeTest { public static void main(String[] args) { (new ScopeTest()).exec(); } private void exec() { (new Runner()).run(); } class Runner { public void run() { Arrays.asList("a", "b","c").stream().collect(Collectors.toList()); } private boolean test() { return false; } } } Add a debug breakpoint at line "Arrays.asList("a","b","c").stream().collect(Collectors.toList());" and run the program. One the breakpoint is hit, evaluate the following expression in the debugshell. Arrays.asList("a", "b", "ac").stream().filter(v -> this.test()).collect(java.util.stream.Collectors.toList()) The evaluation will fail with the following error message Error Message: Missing code implementation in the compiler
With Eclipse 4.17 i get "type not visible", the reason is the remote code snippet doesn't get compiled due to inner class is a package private. Any suggestion to solve this ?
Any suggestions how to handle this inner class thing ? Seems like IJ is handling this. So probably we should be able to fix this as well.
@Sarika any suggestions or can you point to someone who can give some hints.
(In reply to Gayan Perera from comment #3) > @Sarika any suggestions or can you point to someone who can give some hints. To allow this, you’d need to override the behaviour in the snippet compiler.
(In reply to Jesper Moller from comment #4) > (In reply to Gayan Perera from comment #3) > > @Sarika any suggestions or can you point to someone who can give some hints. > > To allow this, you’d need to override the behaviour in the snippet compiler. do you suggest that we inject the methods and variables in private class into the snippet ? Or should we extract a dummy class in the snippet level which has the same signatures and variable so that the snippet gets compiled ? But not sure if that will work with the debugger engine when the evaluations happens even though these kind of things works in javascript world.
(In reply to Gayan Perera from comment #5) > (In reply to Jesper Moller from comment #4) > > (In reply to Gayan Perera from comment #3) > > > @Sarika any suggestions or can you point to someone who can give some hints. > > > > To allow this, you’d need to override the behaviour in the snippet compiler. > > do you suggest that we inject the methods and variables in private class > into the snippet ? > > Or should we extract a dummy class in the snippet level which has the same > signatures and variable so that the snippet gets compiled ? > > But not sure if that will work with the debugger engine when the evaluations > happens even though these kind of things works in javascript world. Even in debugger dummy classes are inserted now also to get it compiled by JDT Core. So you can try extracting a dummy class.
(In reply to Sarika Sinha from comment #6) > (In reply to Gayan Perera from comment #5) > > (In reply to Jesper Moller from comment #4) > > > (In reply to Gayan Perera from comment #3) > > > > @Sarika any suggestions or can you point to someone who can give some hints. > > > > > > To allow this, you’d need to override the behaviour in the snippet compiler. > > > > do you suggest that we inject the methods and variables in private class > > into the snippet ? > > > > Or should we extract a dummy class in the snippet level which has the same > > signatures and variable so that the snippet gets compiled ? > > > > But not sure if that will work with the debugger engine when the evaluations > > happens even though these kind of things works in javascript world. > > Even in debugger dummy classes are inserted now also to get it compiled by > JDT Core. So you can try extracting a dummy class. If I understand you correctly you are suggesting to extract a Dummy interface with same method signature and use it in snippet to get it compiled by JDT right ?
(In reply to Gayan Perera from comment #7) > If I understand you correctly you are suggesting to extract a Dummy > interface with same method signature and use it in snippet to get it > compiled by JDT right ? Yes, something like that, but with a twist. You see, for added confusion, there are TWO compilations in effect: The normal JDT Debug snippet compiler recreates the name environment around a snippet by creating the relevant source around it, and inserting a run method for the snippet. This is handled in SourceBasedSourceGenerator (or BinaryBasedSourceGenerator, depending on the origin of the source under the cursor). This produces a source with empty surroundings and the requested snippet, which is then compiled into an AST and translated by ASTInstructionCompiler into an interpreter which can be executed against a JDI Target. This does not introduce new code into the debuggee, and so has no permissions problems. This method uses a "normal" JDT Parser to make the AST, in org.eclipse.jdt.internal.debug.eval.ast.engine.ASTEvaluationEngine.parseCompilationUnit(char[], String, IJavaProject, Map<String, String>) Alongside this, there is the JDT Core "Evaluator" functionality, which is used in some of the other JDT evaluations. JDT Core is used to produce bytecode for a specified snippet, but uses a bunch of specialized Parser and (internal) AST notes, to deal with the scope and context challenges. The central class for this sorcery is org.eclipse.jdt.internal.eval.CodeSnippetParser. The special handling of the JDT Debug snippet compiler for lambdas use the JDT Evaluator, but since the evaluator uses tricks to deal with the context (instead of recreating the source around the snippet as JDT Debug does). That's why you get these problems. So, to work around the issue in the case, you'll have to review all the classes in org.eclipse.jdt.internal.eval. It's tricky, to say the least.
I'm giving up on this issue, i tried for two days the find a way forward but out of luck :(. if someone can tell me what needs to be done i would be happy to help out, compilers and parsers is not my strong points.
Created attachment 284663 [details] Stacktrace Attached is the stacktraces where output of "canBeSeenBy" needs to be always true for debug to be able to procced with finding a solution to this. @Manoj! Can you look into this and see if somehow Debug can indicate this to Core and core can accordingly ignore "canBeSeenBy".
@Manoj any updates from you on this issue ?
Any updates from anyone @Manoj and @Sarika ?
(In reply to Sarika Sinha from comment #10) > Created attachment 284663 [details] > Stacktrace > > Attached is the stacktraces where output of "canBeSeenBy" needs to be always > true for debug to be able to procced with finding a solution to this. > > @Manoj! > Can you look into this and see if somehow Debug can indicate this to Core > and core can accordingly ignore "canBeSeenBy". @Sarika: Just a quick check - Is the ST on master or 4.17? How do you reproduce the ST which you have added? From comment 0 and comment 1 I understand that the observed error messages are different - Following the test and the steps given by Gayan,On master, I could reproduce the error Gayan mentioned with an ST : ProblemReporter.attemptToReturnNonVoidExpression(ReturnStatement, TypeBinding) line: 1218 ReturnStatement.resolve(BlockScope) line: 324 MethodDeclaration(AbstractMethodDeclaration).resolveStatements() line: 661 MethodDeclaration.resolveStatements() line: 362 MethodDeclaration(AbstractMethodDeclaration).resolve(ClassScope) line: 570 ... which looks different from the ST which you posted. Further, I do a get an ST similar to what you shared once I put a breakpoint at: 1432: if (!currentType.canBeSeenBy(this)) with ST ClassScope(Scope).findField(TypeBinding, char[], InvocationSite, boolean, boolean) line: 1432 ClassScope(Scope).findField(TypeBinding, char[], InvocationSite, boolean) line: 1382 MethodScope(Scope).getBinding(char[], int, InvocationSite, boolean) line: 2119 Argument.bind(MethodScope, TypeBinding, boolean) line: 122 LambdaExpression.resolveType(BlockScope, boolean) line: 385 .. However, I don't see canBeSeen() returning false for any of the fields. If that is the case, the api which you have asked would not make a difference. maybe I am missing something here in trying to reproduce the exact ST, can you please clarify? [please note that I have taken the latest code on master]
@Manoj i think the error messages should be different. Because there was fixes i did my self in this area i think. On the master i now get 3 errors which says ScopeTest.Runner cannot be accessed or something. If you want i can test on latest master and post the error messages. The canBeSeen methods fail when compiling the CodeSnippet for RemoteEvaluator which compiles the lambda expression and push it to debugger.
I checked with latest master on both jdt.core and jdt.debug, seems like i don't have local changes. I have some breakpoint which hacks some variables, i have attached the breakpoint to try out. You need to evaluate the expression Arrays.asList("a", "b", "ac").stream().filter(v -> this.test()).collect(java.util.stream.Collectors.toList()) In the debug shell.
Created attachment 284723 [details] breakpoint
Code from Comment 0, is not going through that stacktrace. I tried the following code: import java.lang.Thread.State; import java.util.Arrays; import java.util.stream.Collectors; public class Application { public static void main(String[] args) { (new Application()).runInner(); } private void runInner() { (new InnerPrivate()).print(); } private void foo(State state) { } class InnerPrivate { public void print() { Arrays.asList("a", "b","c").stream().collect(Collectors.counting()); } private boolean test() { return false; } } } And this goes through canbeSeen and RemoteEvaluatorBuilder. canBeseen methods return true but then it fails with Evaluation failed. Reason(s): [Missing code implementation in the compiler] With the following stack. Thread [ModalContext] (Suspended (breakpoint at line 6894 in ProblemReporter)) owns: Object (id=15712) ProblemReporter.needImplementation(ASTNode) line: 6894 TypeAnnotationCodeStream(CodeStream).generateOuterAccess(Object[], ASTNode, Binding, Scope) line: 2546 TypeAnnotationCodeStream(StackMapFrameCodeStream).generateOuterAccess(Object[], ASTNode, Binding, Scope) line: 285 CodeSnippetSingleNameReference.generateCode(BlockScope, CodeStream, boolean) line: 299 CodeSnippetMessageSend.generateCode(BlockScope, CodeStream, boolean) line: 113 LambdaExpression.generateCode(ClassFile) line: 1293 LambdaExpression.generateCode(ClassScope, ClassFile) line: 1238 CodeSnippetClassFile(ClassFile).addSpecialMethods(TypeDeclaration) line: 1124 CodeSnippetTypeDeclaration.generateCode(ClassFile) line: 79 CodeSnippetTypeDeclaration(TypeDeclaration).generateCode(CompilationUnitScope) line: 812 CompilationUnitDeclaration.generateCode() line: 408 CodeSnippetCompiler(Compiler).process(CompilationUnitDeclaration, int) line: 913 CodeSnippetCompiler(Compiler).processCompiledUnits(int, boolean) line: 575 CodeSnippetCompiler(Compiler).compile(ICompilationUnit[], boolean) line: 475 CodeSnippetCompiler(Compiler).compile(ICompilationUnit[]) line: 426 CodeSnippetEvaluator(Evaluator).getClasses() line: 135 EvaluationContext.evaluate(char[], char[][], char[][], int[], char[], boolean, boolean, INameEnvironment, Map<String,String>, IRequestor, IProblemFactory) line: 305 EvaluationContextWrapper.evaluateCodeSnippet(String, String[], String[], int[], IType, boolean, boolean, ICodeSnippetRequestor, IProgressMonitor) line: 234 RemoteEvaluatorBuilder.build() line: 121 ASTInstructionCompiler.visit(LambdaExpression) line: 2955 LambdaExpression.accept0(ASTVisitor) line: 195 LambdaExpression(ASTNode).accept(ASTVisitor) line: 3012 ASTInstructionCompiler.pushMethodArguments(IMethodBinding, List<Expression>) line: 3156 ASTInstructionCompiler.visit(MethodInvocation) line: 3089 MethodInvocation.accept0(ASTVisitor) line: 220 MethodInvocation(ASTNode).accept(ASTVisitor) line: 3012 ASTInstructionCompiler.visit(MethodInvocation) line: 3084 MethodInvocation.accept0(ASTVisitor) line: 220 MethodInvocation(ASTNode).accept(ASTVisitor) line: 3012 ReturnStatement(ASTNode).acceptChild(ASTVisitor, ASTNode) line: 3060 ReturnStatement.accept0(ASTVisitor) line: 128 ReturnStatement(ASTNode).accept(ASTVisitor) line: 3012 Block(ASTNode).acceptChildren(ASTVisitor, ASTNode$NodeList) line: 3083 Block.accept0(ASTVisitor) line: 128 Block(ASTNode).accept(ASTVisitor) line: 3012 MethodDeclaration(ASTNode).acceptChild(ASTVisitor, ASTNode) line: 3060 MethodDeclaration.accept0(ASTVisitor) line: 698 MethodDeclaration(ASTNode).accept(ASTVisitor) line: 3012 TypeDeclaration(ASTNode).acceptChildren(ASTVisitor, ASTNode$NodeList) line: 3083 TypeDeclaration.accept0(ASTVisitor) line: 526 TypeDeclaration(ASTNode).accept(ASTVisitor) line: 3012 TypeDeclaration(ASTNode).acceptChildren(ASTVisitor, ASTNode$NodeList) line: 3083 TypeDeclaration.accept0(ASTVisitor) line: 526 TypeDeclaration(ASTNode).accept(ASTVisitor) line: 3012 CompilationUnit(ASTNode).acceptChildren(ASTVisitor, ASTNode$NodeList) line: 3083 CompilationUnit.accept0(ASTVisitor) line: 258 CompilationUnit(ASTNode).accept(ASTVisitor) line: 3012 ASTEvaluationEngine.createExpressionFromAST(String, EvaluationSourceGenerator, CompilationUnit) line: 654 ASTEvaluationEngine.getCompiledExpression(String, IJavaStackFrame) line: 394 ASTEvaluationEngine.evaluate(String, IJavaStackFrame, IEvaluationListener, int, boolean) line: 149 EvaluateAction$1.run(IProgressMonitor) line: 261 ModalContext$ModalContextThread.run() line: 122
@Sarika did you try adding the conditional breakpoints with the new code ? That should resolve the error message you are getting.
(In reply to Gayan Perera from comment #18) > @Sarika did you try adding the conditional breakpoints with the new code ? > That should resolve the error message you are getting. I have the conditional breakpoint. It doesn't hit the RemoteEvaluator class itself.
What is the expression you are evaluating?
(In reply to Gayan Perera from comment #20) > What is the expression you are evaluating? same as: Arrays.asList("a", "b", "ac").stream().filter(v -> this.test()).collect(java.util.stream.Collectors.toList());
Thats strange. I check if something extra happens in my workspace.
Created attachment 284747 [details] temp code patch @Sarika please try with the patch that i have done in jdt.core in my workspace. This was created using git diff
(In reply to Gayan Perera from comment #23) > Created attachment 284747 [details] > temp code patch > > @Sarika please try with the patch that i have done in jdt.core in my > workspace. This was created using git diff I tried this and now I don't get NPE. I see that org.eclipse.jdt.internal.compiler.lookup.Scope.getConstructor0(ReferenceBinding, TypeBinding[], InvocationSite) calls org.eclipse.jdt.internal.compiler.lookup.MethodBinding.canBeSeenBy(InvocationSite, Scope) and fails at return invocationType.fPackage == this.declaringClass.fPackage; as invocationType.fPackage = package tt and this.declaringClass.fPackage = package org.eclipse.jdt.internal.eval.target
@Sarika do you mean that now its working with patches and debug point based modifications ? Try the new example i posted, because the debug point hacks are based on my new code which has Application class.
(In reply to Gayan Perera from comment #25) > @Sarika do you mean that now its working with patches and debug point based > modifications ? Try the new example i posted, because the debug point hacks > are based on my new code which has Application class. Busy with RC1 activities. Will try after that.
(In reply to Gayan Perera from comment #25) > @Sarika do you mean that now its working with patches and debug point based > modifications ? Try the new example i posted, because the debug point hacks > are based on my new code which has Application class. Yes with JDT Core patch and the "Application" class evaluation works.
@Gayan, So can you add the temporary JDT Core patch and then JDT Debug patch solution? Manoj will look at the JDT Core and improve it but we can proceed with Debug thing for the problem described in Comment 1 ?
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.