Polishing

This commit is contained in:
BoykoAlex
2019-06-06 13:20:10 -04:00
parent f87d7b602b
commit 72a35bd615
4 changed files with 183 additions and 222 deletions

View File

@@ -1,3 +1,13 @@
/*******************************************************************************
* Copyright (c) 2019 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.utils;
import java.lang.reflect.Constructor;
@@ -28,6 +38,13 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Supplier;
/**
* Reflection based implementation of JDT package public CompilationUnitResolver.
* It is used to resolve the {@link CompilationUnitDeclaration}
*
* @author Alex Boyko
*
*/
class CUResolver {
private static final Logger log = LoggerFactory.getLogger(CUResolver.class);
@@ -65,40 +82,7 @@ class CUResolver {
return null;
}
};
private static final Supplier<Field> BITS_FIELD = () -> {
try {
Field field = ASTParser.class.getDeclaredField("bits");
field.setAccessible(true);
return field;
} catch (SecurityException | NoSuchFieldException e) {
log.error("{}", e);
return null;
}
};
private static final Supplier<Field> WORKING_COPY_OWNER_FIELD = () -> {
try {
Field field = ASTParser.class.getDeclaredField("workingCopyOwner");
field.setAccessible(true);
return field;
} catch (SecurityException | NoSuchFieldException e) {
log.error("{}", e);
return null;
}
};
private static final Supplier<Field> API_LEVEL_FIELD = () -> {
try {
Field field = ASTParser.class.getDeclaredField("apiLevel");
field.setAccessible(true);
return field;
} catch (SecurityException | NoSuchFieldException e) {
log.error("{}", e);
return null;
}
};
private static final Supplier<Class<?>> COMPILATION_UNIT_RESOLVER_CLASS = () -> {
try {
return Class.forName("org.eclipse.jdt.core.dom.CompilationUnitResolver");
@@ -272,7 +256,7 @@ class CUResolver {
};
static CompilationUnitDeclaration resolve(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit,
List<Classpath> classpaths, Map options, int flags, INameEnvironmentWithProgress environment)
List<Classpath> classpaths, Map<String, String> options, int flags, INameEnvironmentWithProgress environment)
throws JavaModelException {
try {
@@ -316,7 +300,7 @@ class CUResolver {
return null;
}
static CompilationUnitDeclaration parse(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit, Map options, int flags) {
static CompilationUnitDeclaration parse(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit, Map<String, String> options, int flags) {
try {
return (CompilationUnitDeclaration) PARSE_METHOD.get()
.invoke(null, sourceUnit, null, options, flags);
@@ -330,7 +314,7 @@ class CUResolver {
CompilationUnitDeclaration compilationUnitDeclaration,
char[] source,
int apiLevel,
Map options,
Map<String, String> options,
boolean needToResolveBindings,
WorkingCopyOwner owner,
int flags) {
@@ -353,47 +337,7 @@ class CUResolver {
return null;
}
static final Supplier<Integer> BINDING_RECOVERY_FLAG = () -> {
try {
Class<?> clazz = COMPILATION_UNIT_RESOLVER_CLASS.get();
if (clazz != null) {
Field field = clazz.getDeclaredField("BINDING_RECOVERY");
field.setAccessible(true);
return field.getInt(null);
}
} catch (Exception e) {
log.error("{}", e);
}
return 0;
};
static final Supplier<Integer> IGNORE_METHOD_BODIES_FLAG = () -> {
try {
Class<?> clazz = COMPILATION_UNIT_RESOLVER_CLASS.get();
if (clazz != null) {
Field field = clazz.getDeclaredField("IGNORE_METHOD_BODIES");
field.setAccessible(true);
return field.getInt(null);
}
} catch (Exception e) {
log.error("{}", e);
}
return 0;
};
static final Supplier<Integer> STATEMENT_RECOVERY_FLAG = () -> {
try {
Class<?> clazz = COMPILATION_UNIT_RESOLVER_CLASS.get();
if (clazz != null) {
Field field = clazz.getDeclaredField("STATEMENT_RECOVERY");
field.setAccessible(true);
return field.getInt(null);
}
} catch (Exception e) {
log.error("{}", e);
}
return 0;
};
static INameEnvironmentWithProgress createLookupEnvironment(Classpath[] classpath) {
try {
return (INameEnvironmentWithProgress) LOOKUP_ENVIRONMENT_CONSTRUCTOR.get().newInstance(classpath, null, new NullProgressMonitor());
@@ -413,32 +357,5 @@ class CUResolver {
}
return null;
}
static int getBits(ASTParser parser) {
try {
return BITS_FIELD.get().getInt(parser);
} catch (IllegalAccessException | IllegalArgumentException e) {
log.error("{}", e);
}
return 0;
}
static WorkingCopyOwner getWorkingCopyOwner(ASTParser parser) {
try {
return (WorkingCopyOwner) WORKING_COPY_OWNER_FIELD.get().get(parser);
} catch (IllegalArgumentException | IllegalAccessException e) {
log.error("{}", e);
}
return null;
}
static int getApiLevel(ASTParser parser) {
try {
return API_LEVEL_FIELD.get().getInt(parser);
} catch (IllegalArgumentException | IllegalAccessException e) {
log.error("{}", e);
}
return 0;
}
}

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2018 Pivotal, Inc.
* Copyright (c) 2017, 2019 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -222,44 +222,44 @@ public final class CompilationUnitCache implements DocumentContentProvider {
}
}
public static CompilationUnit parse(TextDocument document, IJavaProject project) throws Exception {
String[] classpathEntries = getClasspathEntries(project);
String docURI = document.getUri();
String unitName = docURI.substring(docURI.lastIndexOf("/"));
char[] source = document.get(0, document.getLength()).toCharArray();
return parse(source, docURI, unitName, classpathEntries);
}
public CompilationUnit parse(String uri, char[] source, IJavaProject project) throws Exception {
String[] classpathEntries = getClasspathEntries(project);
String unitName = uri.substring(uri.lastIndexOf("/"));
return parse(source, uri, unitName, classpathEntries);
}
public static CompilationUnit parse(char[] source, String docURI, String unitName, String[] classpathEntries) throws Exception {
ASTParser parser = ASTParser.newParser(AST.JLS11);
Map<String, String> options = JavaCore.getOptions();
JavaCore.setComplianceOptions(JavaCore.VERSION_11, options);
parser.setCompilerOptions(options);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setStatementsRecovery(true);
parser.setBindingsRecovery(true);
parser.setResolveBindings(true);
String[] sourceEntries = new String[] {};
parser.setEnvironment(classpathEntries, sourceEntries, null, false);
parser.setUnitName(unitName);
parser.setSource(source);
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
return cu;
}
// public static CompilationUnit parse(TextDocument document, IJavaProject project) throws Exception {
// String[] classpathEntries = getClasspathEntries(project);
// String docURI = document.getUri();
// String unitName = docURI.substring(docURI.lastIndexOf("/"));
// char[] source = document.get(0, document.getLength()).toCharArray();
// return parse(source, docURI, unitName, classpathEntries);
// }
//
// public CompilationUnit parse(String uri, char[] source, IJavaProject project) throws Exception {
// String[] classpathEntries = getClasspathEntries(project);
// String unitName = uri.substring(uri.lastIndexOf("/"));
// return parse(source, uri, unitName, classpathEntries);
// }
//
// public static CompilationUnit parse(char[] source, String docURI, String unitName, String[] classpathEntries) throws Exception {
// ASTParser parser = ASTParser.newParser(AST.JLS11);
// Map<String, String> options = JavaCore.getOptions();
// JavaCore.setComplianceOptions(JavaCore.VERSION_11, options);
// parser.setCompilerOptions(options);
// parser.setKind(ASTParser.K_COMPILATION_UNIT);
// parser.setStatementsRecovery(true);
// parser.setBindingsRecovery(true);
// parser.setResolveBindings(true);
//
// String[] sourceEntries = new String[] {};
// parser.setEnvironment(classpathEntries, sourceEntries, null, false);
//
// parser.setUnitName(unitName);
// parser.setSource(source);
//
// CompilationUnit cu = (CompilationUnit) parser.createAST(null);
//
// return cu;
// }
public static CompilationUnit parse2(char[] source, String docURI, String unitName, String[] classpathEntries, INameEnvironmentWithProgress environment) throws Exception {
List<Classpath> classpaths = createClasspath(classpathEntries);
return parse2(source, docURI, unitName, classpaths, environment);
public static CompilationUnit parse2(char[] source, String docURI, String unitName, IJavaProject project) throws Exception {
List<Classpath> classpaths = createClasspath(getClasspathEntries(project));
return parse2(source, docURI, unitName, classpaths, null);
}
private static CompilationUnit parse2(char[] source, String docURI, String unitName, List<Classpath> classpaths, INameEnvironmentWithProgress environment) throws Exception {

View File

@@ -0,0 +1,123 @@
/*******************************************************************************
* Copyright (c) 2019 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.utils.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.net.URI;
import java.net.URL;
import org.apache.commons.io.IOUtils;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.junit.Before;
import org.junit.Test;
import org.springframework.ide.vscode.boot.java.links.SourceLinks;
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
public class AstParserTest {
private ProjectsHarness projects = ProjectsHarness.INSTANCE;
private MavenJavaProject jp;
@Before
public void setup() throws Exception {
jp = projects.mavenProject("empty-boot-15-web-app");
assertTrue(jp.getIndex().findType("org.springframework.boot.SpringApplication").exists());
}
@Test
public void test1() throws Exception {
URL sourceUrl = SourceLinks.source(jp, "org.springframework.boot.SpringApplication").get();
URI uri = sourceUrl.toURI();
String unitName = "SpringApplication";
char[] content = IOUtils.toString(uri).toCharArray();
CompilationUnit cu = CompilationUnitCache.parse2(content, uri.toString(), unitName, jp);
assertNotNull(cu);
cu.accept(new ASTVisitor() {
@Override
public boolean visit(TypeDeclaration node) {
ITypeBinding binding = node.resolveBinding();
assertNotNull(binding);
return super.visit(node);
}
@Override
public boolean visit(SingleMemberAnnotation node) {
IAnnotationBinding annotationBinding = node.resolveAnnotationBinding();
assertNotNull(annotationBinding);
ITypeBinding binding = node.resolveTypeBinding();
assertNotNull(binding);
return super.visit(node);
}
@Override
public boolean visit(NormalAnnotation node) {
IAnnotationBinding annotationBinding = node.resolveAnnotationBinding();
assertNotNull(annotationBinding);
ITypeBinding binding = node.resolveTypeBinding();
assertNotNull(binding);
return super.visit(node);
}
@Override
public boolean visit(MarkerAnnotation node) {
IAnnotationBinding annotationBinding = node.resolveAnnotationBinding();
assertNotNull(annotationBinding);
ITypeBinding binding = node.resolveTypeBinding();
assertNotNull(binding);
return super.visit(node);
}
@Override
public boolean visit(MethodDeclaration node) {
IMethodBinding binding = node.resolveBinding();
assertNotNull(binding);
if (node.getReturnType2() != null) {
ITypeBinding returnTypeBinding = node.getReturnType2().resolveBinding();
assertNotNull(returnTypeBinding);
}
return super.visit(node);
}
@Override
public boolean visit(FieldDeclaration node) {
ITypeBinding binding = node.getType().resolveBinding();
assertNotNull(binding);
return super.visit(node);
}
});
}
}

View File

@@ -1,79 +0,0 @@
package org.springframework.ide.vscode.boot.test;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.net.URI;
import java.net.URL;
import java.util.stream.Stream;
import org.apache.commons.io.IOUtils;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.junit.Before;
import org.junit.Test;
import org.springframework.ide.vscode.boot.java.links.SourceLinks;
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
import org.springframework.ide.vscode.commons.java.IClasspath;
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
public class SomeTest {
private ProjectsHarness projects = ProjectsHarness.INSTANCE;
private MavenJavaProject jp;
@Before
public void setup() throws Exception {
jp = projects.mavenProject("empty-boot-15-web-app");
assertTrue(jp.getIndex().findType("org.springframework.boot.SpringApplication").exists());
}
@Test
public void test1() throws Exception {
URL sourceUrl = SourceLinks.source(jp, "org.springframework.boot.SpringApplication").get();
URI uri = sourceUrl.toURI();
String unitName = "SpringApplication";
char[] content = IOUtils.toString(uri).toCharArray();
CompilationUnit cu = CompilationUnitCache.parse2(content, uri.toString(), unitName, getClasspathEntries(jp), null);
System.out.println(cu);
}
// @Test
// public void test2() throws Exception {
// URL sourceUrl = SourceLinks.source(jp, "org.springframework.boot.SpringApplication").get();
//
// URI uri = sourceUrl.toURI();
//
// String unitName = "SpringApplication";
//
// char[] content = IOUtils.toString(uri).toCharArray();
//
// CompilationUnit cu = CompilationUnitCache.parse(content, uri.toString(), unitName, getClasspathEntries(jp));
//
// System.out.println(cu);
// }
private static String[] getClasspathEntries(IJavaProject project) throws Exception {
if (project == null) {
return new String[0];
} else {
IClasspath classpath = project.getClasspath();
Stream<File> classpathEntries = IClasspathUtil.getAllBinaryRoots(classpath).stream();
return classpathEntries
.filter(file -> file.exists())
.map(file -> file.getAbsolutePath()).toArray(String[]::new);
}
}
}