Skip to content

Commit

Permalink
[NETBEANS-253] Fixing watches with lambdas. (apache#358)
Browse files Browse the repository at this point in the history
-passing an URI to the created (memory) FileObject when compiling a class using JavaSourceUtilImpl to prevent exceptions
-improving type detection for watches (don't using Trees.getElement(...).getReturnType() and alike, but rather Trees.getTypeMirror(...), as the latter has generics instantiated, etc.)
  • Loading branch information
jlahoda authored and Geertjan Wielenga committed Jan 31, 2018
1 parent 7aeeab1 commit 41da26b
Show file tree
Hide file tree
Showing 6 changed files with 295 additions and 29 deletions.
31 changes: 31 additions & 0 deletions debugger.jpda.projects/nbproject/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,42 @@
<code-name-base>org.netbeans.libs.junit4</code-name-base>
<compile-dependency/>
</test-dependency>
<test-dependency>
<code-name-base>org.netbeans.modules.classfile</code-name-base>
<compile-dependency/>
</test-dependency>
<test-dependency>
<code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
<compile-dependency/>
<test/>
</test-dependency>
<test-dependency>
<code-name-base>org.netbeans.modules.java.source</code-name-base>
<compile-dependency/>
</test-dependency>
<test-dependency>
<code-name-base>org.netbeans.modules.java.source.base</code-name-base>
<compile-dependency/>
<test/>
</test-dependency>
<test-dependency>
<code-name-base>org.netbeans.modules.nbjunit</code-name-base>
<recursive/>
<compile-dependency/>
</test-dependency>
<test-dependency>
<code-name-base>org.netbeans.modules.parsing.indexing</code-name-base>
<compile-dependency/>
<test/>
</test-dependency>
<test-dependency>
<code-name-base>org.netbeans.modules.parsing.nb</code-name-base>
<compile-dependency/>
</test-dependency>
<test-dependency>
<code-name-base>org.netbeans.modules.projectapi.nb</code-name-base>
<compile-dependency/>
</test-dependency>
</test-type>
</test-dependencies>
<friend-packages>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ private boolean isMethodCode() {
public Void visitReturn(ReturnTree node, Void p) {
if (isMethodCode() /*&& phase == PHASE_INSIDE_SELECTION*/) {
hasReturns = true;
Element retExpElem = info.getTrees().getElement(new TreePath(getCurrentPath(), node.getExpression())); //.asType().toString();
if (retExpElem != null) {
returnTypes.add(getElementType(retExpElem));
TypeMirror type = info.getTrees().getTypeMirror(new TreePath(getCurrentPath(), node.getExpression())); //.asType().toString();
if (type != null && type.getKind() != TypeKind.ERROR) {
returnTypes.add(type);
} else {
// Unresolved element
TypeElement object = info.getElements().getTypeElement("java.lang.Object");
Expand All @@ -152,36 +152,15 @@ public Void visitExpressionStatement(ExpressionStatementTree node, Void p) {
if (node == lastStatement) {
if (!hasReturns) {
ExpressionTree expression = node.getExpression();
Element retExpElem = info.getTrees().getElement(new TreePath(getCurrentPath(), expression));
if (retExpElem == null) {
TreePath elementPath = null;
if (Tree.Kind.ASSIGNMENT.equals(expression.getKind())) {
elementPath = new TreePath(getCurrentPath(), ((AssignmentTree) expression).getVariable());
} else if (Tree.Kind.VARIABLE.equals(expression.getKind())) {
elementPath = new TreePath(getCurrentPath(), ((VariableTree) expression));
}
if (elementPath != null) {
retExpElem = info.getTrees().getElement(elementPath);
}
}
if (retExpElem != null && !TypeKind.ERROR.equals(retExpElem.asType().getKind())) {
returnTypes.add(getElementType(retExpElem));
TypeMirror type = info.getTrees().getTypeMirror(new TreePath(getCurrentPath(), expression));
if (type != null && !TypeKind.ERROR.equals(type.getKind())) {
returnTypes.add(type);
}
}
}
return super.visitExpressionStatement(node, p);
}

private TypeMirror getElementType(Element element) {
switch (element.getKind()) {
case METHOD:
case CONSTRUCTOR:
return ((ExecutableElement) element).getReturnType();
default:
return element.asType();
}
}

Set<VariableElement> getReferencedVariables() {
return referencedVariables;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.debugger.jpda.projects;

import com.sun.source.tree.StatementTree;
import com.sun.source.util.SourcePositions;
import com.sun.source.util.TreePath;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Method;
import java.io.ByteArrayInputStream;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.source.CompilationController;
import org.netbeans.api.java.source.JavaSource;
import org.netbeans.api.java.source.JavaSource.Phase;
import org.netbeans.api.java.source.SourceUtilsTestUtil;
import org.netbeans.api.java.source.TestUtilities;
import org.netbeans.junit.NbTestCase;
import org.netbeans.spi.java.classpath.ClassPathProvider;
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;

/**
*
* @author lahvac
*/
public class CodeSnippetCompilerTest extends NbTestCase {

public CodeSnippetCompilerTest(String name) {
super(name);
}

private FileObject wd;
private FileObject root;

@Override
protected void setUp() throws Exception {
super.setUp();
clearWorkDir();
SourceUtilsTestUtil.prepareTest(new String[0], new Object[] {
new ClassPathProvider() {
@Override
public ClassPath findClassPath(FileObject file, String type) {
if (type == ClassPath.SOURCE) {
return ClassPathSupport.createClassPath(root);
}
return null;
}
}
});
wd = FileUtil.toFileObject(FileUtil.normalizeFile(getWorkDir()));
root = FileUtil.createFolder(wd, "src"); //NOI18N
}

private static FileObject createFile(
final FileObject root,
final String path,
final String content) throws Exception {
FileObject file = FileUtil.createData(root, path);
TestUtilities.copyStringToFile(file, content);
return file;
}

public void testInferResultType() throws Exception {
String code = "package test;\n class A { public void test(java.util.List<String> l) { } }";
String watch = "l.stream().map(s -> s.length()).collect(java.util.stream.Collectors.toList());";
int pos = code.indexOf("{", code.indexOf("{") + 1);
FileObject java = createFile(root, "test/A.java", code); //NOI18N
JavaSource.forFileObject(java).runUserActionTask((CompilationController cc) -> {
cc.toPhase(Phase.RESOLVED);
TreePath posPath = cc.getTreeUtilities().pathFor(pos);
StatementTree tree = cc.getTreeUtilities().parseStatement(
watch,
new SourcePositions[1]
);
cc.getTreeUtilities().attributeTree(tree, cc.getTrees().getScope(posPath));
TreePath tp = new TreePath(posPath, tree);
ClassToInvoke cti = CodeSnippetCompiler.compileToClass(cc, watch, 0, cc.getJavaSource(), java, -1, tp, tree, false);

ClassFile cf = ClassFile.read(new ByteArrayInputStream(cti.bytecode));

for (Method m : cf.methods) {
if (cf.constant_pool.getUTF8Value(m.name_index).equals("invoke")) {
assertEquals("(Ljava/util/List;)Ljava/util/List;", cf.constant_pool.getUTF8Value(m.descriptor.index));
}
}
}, true);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ protected Map<String, byte[]> generate(
final JavaFileObject toCompile = FileObjects.memoryFileObject(
ncs[0],
ncs[1]+'.'+file.getExt(),
file.toURI(),
System.currentTimeMillis(),
content);
boolean success = false;
final TransactionContext ctx = TransactionContext.beginTrans()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,11 @@ public Collection<? extends Processor> resolveProcessors(boolean onScan) {
if (pp == null) {
pp = ClassPath.EMPTY;
}
ClassLoader contextCL = Context.class.getClassLoader();
cl = CachingArchiveClassLoader.forClassPath(
pp,
new BypassOpenIDEUtilClassLoader(Context.class.getClassLoader()),
contextCL != null ? new BypassOpenIDEUtilClassLoader(contextCL)
: ClassLoader.getSystemClassLoader().getParent(),
usedRoots);
classLoaderCache = !DISABLE_CLASSLOADER_CACHE ? new ClassLoaderRef(cl, root, isModule) : null;
} else {
Expand Down
Loading

0 comments on commit 41da26b

Please sign in to comment.