From dd1aaad43f39e5fb0950b25c7f1ffe207b413811 Mon Sep 17 00:00:00 2001
From: BoykoAlex
Date: Fri, 11 Feb 2022 15:40:55 -0500
Subject: [PATCH] Remove JDT
---
.../spring-boot-language-server/pom.xml | 4 +-
.../boot/app/BootLanguageServerBootApp.java | 5 +-
.../BootJavaLanguageServerComponents.java | 2 +-
.../annotations/AnnotationHierarchies.java | 21 +-
.../boot/java/beans/BeansSymbolProvider.java | 5 -
.../handlers/BootJavaReferencesHandler.java | 86 ++-
.../boot/java/handlers/ReferenceProvider.java | 12 +-
.../boot/java/jdt/imports/ImportRewrite.java | 558 ------------------
.../DefaultJavaElementLocationProvider.java | 10 -
.../BeanInjectedIntoHoverProvider.java | 2 -
.../boot/java/livehover/LiveHoverUtils.java | 2 -
.../ide/vscode/boot/java/utils/ASTUtils.java | 306 ----------
.../vscode/boot/java/utils/CUResolver.java | 361 -----------
.../boot/java/utils/CompilationUnitCache.java | 307 ----------
.../NameEnvironmentAwareASTRequestor.java | 63 --
.../java/utils/ORCompilationUnitCache.java | 5 +-
.../java/utils/SpringIndexerJavaContext.java | 1 -
.../SpringIndexerJavaDependencyTracker.java | 6 +-
.../java/value/ValueCompletionProcessor.java | 14 +-
.../ValuePropertyReferencesProvider.java | 35 +-
.../boot/bootiful/PropertyEditorTestConf.java | 6 +-
.../boot/bootiful/XmlBeansTestConf.java | 4 +-
.../boot/java/utils/test/AstParserTest.java | 123 ----
.../utils/test/CompilationUnitCacheTest.java | 4 +-
.../java/value/test/ValueCompletionTest.java | 4 +-
.../ValueSpelExpressionValidationTest.java | 3 +-
.../boot/test/DefinitionLinkAsserts.java | 154 +++--
27 files changed, 163 insertions(+), 1940 deletions(-)
delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/jdt/imports/ImportRewrite.java
delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java
delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/CUResolver.java
delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/CompilationUnitCache.java
delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/NameEnvironmentAwareASTRequestor.java
delete mode 100644 headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/AstParserTest.java
diff --git a/headless-services/spring-boot-language-server/pom.xml b/headless-services/spring-boot-language-server/pom.xml
index 298c81400..2b6231485 100644
--- a/headless-services/spring-boot-language-server/pom.xml
+++ b/headless-services/spring-boot-language-server/pom.xml
@@ -99,12 +99,12 @@
commons-language-server${dependencies.version}
-
+ org.openrewriterewrite-java${rewrite-version}
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerBootApp.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerBootApp.java
index 7f82a279b..940ae382f 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerBootApp.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerBootApp.java
@@ -35,7 +35,6 @@ import org.springframework.ide.vscode.boot.java.links.JdtJavaDocumentUriProvider
import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory;
import org.springframework.ide.vscode.boot.java.links.SourceLinks;
import org.springframework.ide.vscode.boot.java.livehover.v2.SpringProcessLiveDataProvider;
-import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
import org.springframework.ide.vscode.boot.java.utils.ORCompilationUnitCache;
import org.springframework.ide.vscode.boot.java.utils.SymbolCache;
import org.springframework.ide.vscode.boot.java.utils.SymbolCacheOnDisc;
@@ -159,8 +158,8 @@ public class BootLanguageServerBootApp {
return new ORCompilationUnitCache(params.projectFinder, server, params.projectObserver);
}
- @Bean CompilationUnitCache cuCache(SimpleLanguageServer server, BootLanguageServerParams params) {
- return new CompilationUnitCache(params.projectFinder, server, params.projectObserver);
+ @Bean ORCompilationUnitCache cuCache(SimpleLanguageServer server, BootLanguageServerParams params) {
+ return new ORCompilationUnitCache(params.projectFinder, server, params.projectObserver);
}
@Bean SpringXMLCompletionEngine xmlCompletionEngine(SimpleLanguageServer server, JavaProjectFinder projectFinder, SpringSymbolIndex symbolIndex, BootJavaConfig config) {
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java
index 71f2135c9..b0e4848e5 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java
@@ -302,7 +302,7 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
providers.put(org.springframework.ide.vscode.boot.java.value.Constants.SPRING_VALUE,
new ValuePropertyReferencesProvider(server));
- return new BootJavaReferencesHandler(this, projectFinder, providers);
+ return new BootJavaReferencesHandler(this, projectFinder, providers, cuCache);
}
protected BootJavaCodeLensEngine createCodeLensEngine(SpringSymbolIndex index) {
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/annotations/AnnotationHierarchies.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/annotations/AnnotationHierarchies.java
index 08956a01c..084fc143c 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/annotations/AnnotationHierarchies.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/annotations/AnnotationHierarchies.java
@@ -18,7 +18,6 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.openrewrite.java.tree.J.Annotation;
import org.openrewrite.java.tree.JavaType.FullyQualified;
import org.openrewrite.java.tree.TypeUtils;
@@ -48,21 +47,15 @@ public abstract class AnnotationHierarchies {
};
public static Collection getDirectSuperAnnotations(FullyQualified type) {
- try {
- List annotations = type.getAnnotations();
- if (annotations != null && !annotations.isEmpty()) {
- ImmutableList.Builder superAnnotations = ImmutableList.builder();
- for (FullyQualified ab : annotations) {
- if (!ignoreAnnotation(ab.getFullyQualifiedName())) {
- superAnnotations.add(ab);
- }
+ List annotations = type.getAnnotations();
+ if (annotations != null && !annotations.isEmpty()) {
+ ImmutableList.Builder superAnnotations = ImmutableList.builder();
+ for (FullyQualified ab : annotations) {
+ if (!ignoreAnnotation(ab.getFullyQualifiedName())) {
+ superAnnotations.add(ab);
}
- return superAnnotations.build();
}
- } catch (AbortCompilation e) {
- log.debug("compilation aborted ", e);
- // ignore this, it is most likely caused by broken source code, a broken
- // classpath, or some optional dependencies not being on the classpath
+ return superAnnotations.build();
}
return ImmutableList.of();
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java
index 17a6db6b9..d64401ddc 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java
@@ -11,12 +11,10 @@
package org.springframework.ide.vscode.boot.java.beans;
import java.util.Collection;
-import java.util.List;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.SymbolKind;
-import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.J.Annotation;
import org.openrewrite.java.tree.J.ClassDeclaration;
@@ -25,13 +23,11 @@ import org.openrewrite.java.tree.J.MethodDeclaration;
import org.openrewrite.java.tree.J.Modifier;
import org.openrewrite.java.tree.JavaType.FullyQualified;
import org.openrewrite.java.tree.JavaType.Method;
-import org.openrewrite.java.tree.JavaType.Parameterized;
import org.openrewrite.java.tree.TypeUtils;
import org.springframework.ide.vscode.boot.java.Annotations;
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
-import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
import org.springframework.ide.vscode.boot.java.utils.FunctionUtils;
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
@@ -42,7 +38,6 @@ import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import com.google.common.collect.ImmutableList;
-import com.google.common.reflect.Parameter;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuple3;
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaReferencesHandler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaReferencesHandler.java
index 289fd3bcd..de6e7c2c0 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaReferencesHandler.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaReferencesHandler.java
@@ -11,24 +11,24 @@
package org.springframework.ide.vscode.boot.java.handlers;
import java.io.File;
+import java.net.URI;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.CancellationException;
import java.util.stream.Stream;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.dom.AST;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.ASTParser;
-import org.eclipse.jdt.core.dom.Annotation;
-import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.ReferenceParams;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
+import org.openrewrite.java.tree.J;
+import org.openrewrite.java.tree.J.Annotation;
+import org.openrewrite.java.tree.JavaType.FullyQualified;
+import org.openrewrite.java.tree.TypeUtils;
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
+import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
+import org.springframework.ide.vscode.boot.java.utils.ORCompilationUnitCache;
import org.springframework.ide.vscode.commons.java.IClasspath;
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
import org.springframework.ide.vscode.commons.java.IJavaProject;
@@ -46,11 +46,14 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
private JavaProjectFinder projectFinder;
private BootJavaLanguageServerComponents server;
private Map referenceProviders;
+ private ORCompilationUnitCache cuCache;
- public BootJavaReferencesHandler(BootJavaLanguageServerComponents server, JavaProjectFinder projectFinder, Map specificProviders) {
+ public BootJavaReferencesHandler(BootJavaLanguageServerComponents server, JavaProjectFinder projectFinder, Map specificProviders, ORCompilationUnitCache cuCache) {
this.server = server;
this.projectFinder = projectFinder;
this.referenceProviders = specificProviders;
+ this.cuCache = cuCache;
+
}
@Override
@@ -83,59 +86,38 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
}
private List extends Location> provideReferences(CancelChecker cancelToken, TextDocument document, int offset) throws Exception {
- ASTParser parser = ASTParser.newParser(AST.JLS16);
- Map options = JavaCore.getOptions();
- JavaCore.setComplianceOptions(JavaCore.VERSION_16, options);
- parser.setCompilerOptions(options);
- parser.setKind(ASTParser.K_COMPILATION_UNIT);
- parser.setStatementsRecovery(true);
- parser.setBindingsRecovery(true);
- parser.setResolveBindings(true);
+ Optional project = projectFinder.find(document.getId());
+ if (project.isPresent()) {
+ return cuCache.withCompilationUnit(project.get(), URI.create(document.getUri()), cu -> {
+ J node = ORAstUtils.findAstNodeAt(cu, offset);
+
+ if (node != null) {
+ cancelToken.checkCanceled();
+ return provideReferencesForAnnotation(cancelToken, node, offset, document);
+ }
- String[] classpathEntries = getClasspathEntries(document);
- String[] sourceEntries = new String[] {};
- parser.setEnvironment(classpathEntries, sourceEntries, null, true);
-
- String docURI = document.getUri();
- String unitName = docURI.substring(docURI.lastIndexOf("/"));
- parser.setUnitName(unitName);
- parser.setSource(document.get(0, document.getLength()).toCharArray());
-
- cancelToken.checkCanceled();
-
- CompilationUnit cu = (CompilationUnit) parser.createAST(null);
- ASTNode node = NodeFinder.perform(cu, offset, 0);
-
- if (node != null) {
- cancelToken.checkCanceled();
- return provideReferencesForAnnotation(cancelToken, node, offset, document);
+ return null;
+ });
+
}
-
return null;
}
- private List extends Location> provideReferencesForAnnotation(CancelChecker cancelToken, ASTNode node, int offset, TextDocument doc) {
- Annotation annotation = null;
-
- while (node != null && !(node instanceof Annotation)) {
- node = node.getParent();
- }
-
+ private List extends Location> provideReferencesForAnnotation(CancelChecker cancelToken, J node, int offset, TextDocument doc) {
if (node != null) {
- annotation = (Annotation) node;
- ITypeBinding type = annotation.resolveTypeBinding();
- if (type != null) {
+ Annotation annotation = ORAstUtils.findNode(node, Annotation.class);
- String qualifiedName = type.getQualifiedName();
- if (qualifiedName != null) {
- ReferenceProvider provider = this.referenceProviders.get(qualifiedName);
- if (provider != null) {
- return provider.provideReferences(cancelToken, node, annotation, type, offset, doc);
- }
+ if (annotation != null) {
+ FullyQualified type = TypeUtils.asFullyQualified(annotation.getType());
+ if (type != null) {
+ ReferenceProvider provider = this.referenceProviders.get(type.getFullyQualifiedName());
+ if (provider != null) {
+ return provider.provideReferences(cancelToken, node, annotation, type, offset, doc);
+ }
}
}
}
-
+
return null;
}
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/ReferenceProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/ReferenceProvider.java
index 42d8a056c..29c833170 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/ReferenceProvider.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/ReferenceProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2017, 2021 Pivotal, Inc.
+ * Copyright (c) 2017, 2022 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
@@ -12,11 +12,11 @@ package org.springframework.ide.vscode.boot.java.handlers;
import java.util.List;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.Annotation;
-import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
+import org.openrewrite.java.tree.J;
+import org.openrewrite.java.tree.J.Annotation;
+import org.openrewrite.java.tree.JavaType.FullyQualified;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
/**
@@ -24,7 +24,7 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
*/
public interface ReferenceProvider {
- List extends Location> provideReferences(CancelChecker cancelToken, ASTNode node, Annotation annotation,
- ITypeBinding type, int offset, TextDocument doc);
+ List extends Location> provideReferences(CancelChecker cancelToken, J node, Annotation annotation,
+ FullyQualified type, int offset, TextDocument doc);
}
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/jdt/imports/ImportRewrite.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/jdt/imports/ImportRewrite.java
deleted file mode 100644
index 4f296061b..000000000
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/jdt/imports/ImportRewrite.java
+++ /dev/null
@@ -1,558 +0,0 @@
-/*******************************************************************************
- * Derived from:
- * org.eclipse.jdt.core.dom.rewrite.ImportRewrite
- *
- * for use in STS4, where IProject and ICompilationUnit are not available when parsing a Java source.
- *
- * Original license:
- *
- * Copyright (c) 2000, 2016 IBM Corporation and others.
- * 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:
- * IBM Corporation - initial API and implementation
- * John Glassmyer - import group sorting is broken - https://bugs.eclipse.org/430303
- * Lars Vogel - Contributions for
- * Bug 473178
- *******************************************************************************/
-package org.springframework.ide.vscode.boot.java.jdt.imports;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.core.dom.ASTParser;
-import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
-import org.eclipse.jdt.core.dom.Comment;
-import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jdt.core.dom.ImportDeclaration;
-import org.eclipse.jdt.core.dom.PackageDeclaration;
-import org.eclipse.jdt.core.dom.PrimitiveType;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
-import org.springframework.ide.vscode.commons.util.text.IDocument;
-
-
-/**
- * The {@link ImportRewrite} helps updating imports following a import order and on-demand imports threshold as configured by a project.
- *
- * The import rewrite is created on a compilation unit and collects references to types that are added or removed. When adding imports, e.g. using
- * {@link #addImport(String)}, the import rewrite evaluates if the type can be imported and returns the a reference to the type that can be used in code.
- * This reference is either unqualified if the import could be added, or fully qualified if the import failed due to a conflict with another element of the same name.
- *
- *
- * On {@link #rewriteImports(IProgressMonitor)} the rewrite translates these descriptions into
- * text edits that can then be applied to the original source. The rewrite infrastructure tries to generate minimal text changes and only
- * works on the import statements. It is possible to combine the result of an import rewrite with the result of a {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite}
- * as long as no import statements are modified by the AST rewrite.
- *
- *
The options controlling the import order and on-demand thresholds are:
- *
{@link #setImportOrder(String[])} specifies the import groups and their preferred order
- *
{@link #setOnDemandImportThreshold(int)} specifies the number of imports in a group needed for a on-demand import statement (star import)
- *
{@link #setStaticOnDemandImportThreshold(int)} specifies the number of static imports in a group needed for a on-demand import statement (star import)
- *
- * This class is not intended to be subclassed.
- *
- * @since 3.2
- */
-@SuppressWarnings({ "rawtypes", "unchecked" })
-public final class ImportRewrite {
-
- /**
- * A {@link ImportRewrite.ImportRewriteContext} can optionally be used in e.g. {@link ImportRewrite#addImport(String, ImportRewrite.ImportRewriteContext)} to
- * give more information about the types visible in the scope. These types can be for example inherited inner types where it is
- * unnecessary to add import statements for.
- *
- *
- *
- * This class can be implemented by clients.
- *
- */
- public static abstract class ImportRewriteContext {
-
- /**
- * Result constant signaling that the given element is know in the context.
- */
- public final static int RES_NAME_FOUND= 1;
-
- /**
- * Result constant signaling that the given element is not know in the context.
- */
- public final static int RES_NAME_UNKNOWN= 2;
-
- /**
- * Result constant signaling that the given element is conflicting with an other element in the context.
- */
- public final static int RES_NAME_CONFLICT= 3;
-
- /**
- * Result constant signaling that the given element must be imported explicitly (and must not be folded into
- * an on-demand import or filtered as an implicit import).
- *
- * @since 3.11
- */
- public final static int RES_NAME_UNKNOWN_NEEDS_EXPLICIT_IMPORT= 4;
-
- /**
- * Kind constant specifying that the element is a type import.
- */
- public final static int KIND_TYPE= 1;
-
- /**
- * Kind constant specifying that the element is a static field import.
- */
- public final static int KIND_STATIC_FIELD= 2;
-
- /**
- * Kind constant specifying that the element is a static method import.
- */
- public final static int KIND_STATIC_METHOD= 3;
-
- /**
- * Searches for the given element in the context and reports if the element is known ({@link #RES_NAME_FOUND}),
- * unknown ({@link #RES_NAME_UNKNOWN}), unknown in the context but known to require an explicit import
- * ({@link #RES_NAME_UNKNOWN_NEEDS_EXPLICIT_IMPORT}), or if its name conflicts ({@link #RES_NAME_CONFLICT})
- * with an other element.
- *
- * @param qualifier The qualifier of the element, can be package or the qualified name of a type
- * @param name The simple name of the element; either a type, method or field name or * for on-demand imports.
- * @param kind The kind of the element. Can be either {@link #KIND_TYPE}, {@link #KIND_STATIC_FIELD} or
- * {@link #KIND_STATIC_METHOD}. Implementors should be prepared for new, currently unspecified kinds and return
- * {@link #RES_NAME_UNKNOWN} by default.
- * @return Returns the result of the lookup. Can be either {@link #RES_NAME_FOUND}, {@link #RES_NAME_UNKNOWN},
- * {@link #RES_NAME_CONFLICT}, or {@link #RES_NAME_UNKNOWN_NEEDS_EXPLICIT_IMPORT}.
- */
- public abstract int findInContext(String qualifier, String name, int kind);
- }
-
- private static final char STATIC_PREFIX= 's';
- private static final char NORMAL_PREFIX= 'n';
-
- private final ImportRewriteContext defaultContext;
-
- private final CompilationUnit astRoot;
-
- private final boolean restoreExistingImports;
- private final List existingImports;
-
-
- private List addedImports;
-
- /**
- * Simple names of non-static imports which must not be reduced into on-demand imports
- * or filtered out as implicit.
- */
- private Set typeExplicitSimpleNames;
-
-
- private boolean filterImplicitImports;
- private boolean useContextToFilterImplicitImports;
-
-
- /**
- * Creates an {@link ImportRewrite} from an AST ({@link CompilationUnit}). The AST has to be created from an
- * {@link ICompilationUnit}, that means {@link ASTParser#setSource(ICompilationUnit)} has been used when creating the
- * AST. If restoreExistingImports is true, all existing imports are kept, and new imports
- * will be inserted at best matching locations. If restoreExistingImports is false, the
- * existing imports will be removed and only the newly added imports will be created.
- *
- * Note that this method is more efficient than using {@link #create(ICompilationUnit, boolean)} if an AST is already available.
- *
- * @param astRoot the AST root node to create the imports for
- * @param restoreExistingImports specifies if the existing imports should be kept or removed.
- * @return the created import rewriter.
- * @throws IllegalArgumentException thrown when the passed AST is null or was not created from a compilation unit.
- */
- public static ImportRewrite create(CompilationUnit astRoot, boolean restoreExistingImports) {
- if (astRoot == null) {
- throw new IllegalArgumentException("AST must not be null"); //$NON-NLS-1$
- }
-
- List existingImport= null;
- if (restoreExistingImports) {
- existingImport= new ArrayList();
- List imports= astRoot.imports();
- for (int i= 0; i < imports.size(); i++) {
- ImportDeclaration curr= (ImportDeclaration) imports.get(i);
- StringBuffer buf= new StringBuffer();
- buf.append(curr.isStatic() ? STATIC_PREFIX : NORMAL_PREFIX).append(curr.getName().getFullyQualifiedName());
- if (curr.isOnDemand()) {
- if (buf.length() > 1)
- buf.append('.');
- buf.append('*');
- }
- existingImport.add(buf.toString());
- }
- }
- return new ImportRewrite(astRoot, existingImport);
- }
-
- private ImportRewrite(CompilationUnit astRoot, List existingImports) {
- this.astRoot= astRoot; // might be null
- if (existingImports != null) {
- this.existingImports= existingImports;
- this.restoreExistingImports= !existingImports.isEmpty();
- } else {
- this.existingImports= new ArrayList();
- this.restoreExistingImports= false;
- }
- this.filterImplicitImports= true;
- // consider that no contexts are used
- this.useContextToFilterImplicitImports = false;
-
- this.defaultContext= new ImportRewriteContext() {
- @Override
- public int findInContext(String qualifier, String name, int kind) {
- return findInImports(qualifier, name, kind);
- }
- };
- this.addedImports= new ArrayList<>();
- this.typeExplicitSimpleNames = new HashSet<>();
- }
-
- /**
- * Returns the default rewrite context that only knows about the imported types. Clients
- * can write their own context and use the default context for the default behavior.
- * @return the default import rewrite context.
- */
- public ImportRewriteContext getDefaultImportRewriteContext() {
- return this.defaultContext;
- }
-
- /**
- * Specifies that implicit imports (for types in java.lang, types in the same package as the rewrite
- * compilation unit, and types in the compilation unit's main type) should not be created, except if necessary to
- * resolve an on-demand import conflict.
- *
- * The filter is enabled by default.
- *
- *
- * Note: {@link #setUseContextToFilterImplicitImports(boolean)} can be used to filter implicit imports
- * when a context is used.
- *
- *
- * @param filterImplicitImports
- * if true, implicit imports will be filtered
- *
- * @see #setUseContextToFilterImplicitImports(boolean)
- */
- public void setFilterImplicitImports(boolean filterImplicitImports) {
- this.filterImplicitImports= filterImplicitImports;
- }
-
- /**
- * Sets whether a context should be used to properly filter implicit imports.
- *
- * By default, the option is disabled to preserve pre-3.6 behavior.
- *
- *
- * When this option is set, the context passed to the addImport*(...) methods is used to determine
- * whether an import can be filtered because the type is implicitly visible. Note that too many imports
- * may be kept if this option is set and addImport*(...) methods are called without a context.
- *
- *
- * @param useContextToFilterImplicitImports the given setting
- *
- * @see #setFilterImplicitImports(boolean)
- * @since 3.6
- */
- public void setUseContextToFilterImplicitImports(boolean useContextToFilterImplicitImports) {
- this.useContextToFilterImplicitImports = useContextToFilterImplicitImports;
- }
-
- private static int compareImport(char prefix, String qualifier, String name, String curr) {
- if (curr.charAt(0) != prefix || !curr.endsWith(name)) {
- return ImportRewriteContext.RES_NAME_UNKNOWN;
- }
-
- curr= curr.substring(1); // remove the prefix
-
- if (curr.length() == name.length()) {
- if (qualifier.length() == 0) {
- return ImportRewriteContext.RES_NAME_FOUND;
- }
- return ImportRewriteContext.RES_NAME_CONFLICT;
- }
- // at this place: curr.length > name.length
-
- int dotPos= curr.length() - name.length() - 1;
- if (curr.charAt(dotPos) != '.') {
- return ImportRewriteContext.RES_NAME_UNKNOWN;
- }
- if (qualifier.length() != dotPos || !curr.startsWith(qualifier)) {
- return ImportRewriteContext.RES_NAME_CONFLICT;
- }
- return ImportRewriteContext.RES_NAME_FOUND;
- }
-
- /**
- * Not API, package visibility as accessed from an anonymous type
- */
- /* package */ final int findInImports(String qualifier, String name, int kind) {
- boolean allowAmbiguity= (kind == ImportRewriteContext.KIND_STATIC_METHOD) || (name.length() == 1 && name.charAt(0) == '*');
- List imports= this.existingImports;
- char prefix= (kind == ImportRewriteContext.KIND_TYPE) ? NORMAL_PREFIX : STATIC_PREFIX;
-
- for (int i= imports.size() - 1; i >= 0 ; i--) {
- String curr= (String) imports.get(i);
- int res= compareImport(prefix, qualifier, name, curr);
- if (res != ImportRewriteContext.RES_NAME_UNKNOWN) {
- if (!allowAmbiguity || res == ImportRewriteContext.RES_NAME_FOUND) {
- if (prefix != STATIC_PREFIX) {
- return res;
- }
- }
- }
- }
-
- String packageName = getPackageName();
- if (kind == ImportRewriteContext.KIND_TYPE) {
- if (this.filterImplicitImports && this.useContextToFilterImplicitImports) {
-
- // [STS4] No ICompilationUnit available as there is no class file or associated IJavaElement available for the source
-
-// String mainTypeSimpleName= JavaCore.removeJavaLikeExtension(this.compilationUnit.getElementName());
-// String mainTypeName= Util.concatenateName(packageName, mainTypeSimpleName, '.');
-// if (qualifier.equals(packageName)
-// || mainTypeName.equals(Util.concatenateName(qualifier, name, '.'))) {
-// return ImportRewriteContext.RES_NAME_FOUND;
-// }
-
- if (this.astRoot != null) {
- List types = this.astRoot.types();
- int nTypes = types.size();
- for (int i = 0; i < nTypes; i++) {
- AbstractTypeDeclaration type = types.get(i);
- SimpleName simpleName = type.getName();
- if (simpleName.getIdentifier().equals(name)) {
- return qualifier.equals(packageName)
- ? ImportRewriteContext.RES_NAME_FOUND
- : ImportRewriteContext.RES_NAME_CONFLICT;
- }
- }
- } else {
-
- // [STS4] No ICompilationUnit available as there is no class file or associated IJavaElement available for the source
-// try {
-// IType[] types = this.compilationUnit.getTypes();
-// int nTypes = types.length;
-// for (int i = 0; i < nTypes; i++) {
-// IType type = types[i];
-// String typeName = type.getElementName();
-// if (typeName.equals(name)) {
-// return qualifier.equals(packageName)
-// ? ImportRewriteContext.RES_NAME_FOUND
-// : ImportRewriteContext.RES_NAME_CONFLICT;
-// }
-// }
-// } catch (JavaModelException e) {
-// // don't want to throw an exception here
-// }
- }
- }
- }
-
- return ImportRewriteContext.RES_NAME_UNKNOWN;
- }
-
- private String getPackageName() {
- // [STS4] No ICompilationUnit available as there is no class file or associated IJavaElement available for the source
-// this.compilationUnit.getParent().getElementName();
- return this.astRoot.getPackage().getName().getFullyQualifiedName();
- }
-
- /**
- * Adds a new import to the rewriter's record and returns a type reference that can be used
- * in the code. The type binding can only be an array or non-generic type.
- *
- * No imports are added for types that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
- *
- *
- * The content of the compilation unit itself is actually not modified
- * in any way by this method; rather, the rewriter just records that a new import has been added.
- *
- * @param qualifiedTypeName the qualified type name of the type to be added
- * @param context an optional context that knows about types visible in the current scope or null
- * to use the default context only using the available imports.
- * @return a type reference for the given qualified type name. The type name is a simple name if an import could be used,
- * or else a qualified name if an import conflict prevented an import.
- */
- public String addImport(String qualifiedTypeName, ImportRewriteContext context) {
- int angleBracketOffset= qualifiedTypeName.indexOf('<');
- if (angleBracketOffset != -1) {
- return internalAddImport(qualifiedTypeName.substring(0, angleBracketOffset), context) + qualifiedTypeName.substring(angleBracketOffset);
- }
- int bracketOffset= qualifiedTypeName.indexOf('[');
- if (bracketOffset != -1) {
- return internalAddImport(qualifiedTypeName.substring(0, bracketOffset), context) + qualifiedTypeName.substring(bracketOffset);
- }
- return internalAddImport(qualifiedTypeName, context);
- }
-
- /**
- * Adds a new import to the rewriter's record and returns a type reference that can be used
- * in the code. The type binding can only be an array or non-generic type.
- *
- * No imports are added for types that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
- *
- *
- * The content of the compilation unit itself is actually not modified
- * in any way by this method; rather, the rewriter just records that a new import has been added.
- *
- * @param qualifiedTypeName the qualified type name of the type to be added
- * @return a type reference for the given qualified type name. The type name is a simple name if an import could be used,
- * or else a qualified name if an import conflict prevented an import.
- */
- public String addImport(String qualifiedTypeName) {
- return addImport(qualifiedTypeName, this.defaultContext);
- }
-
-
-
- private String internalAddImport(String fullTypeName, ImportRewriteContext context) {
- int idx= fullTypeName.lastIndexOf('.');
- String typeContainerName, typeName;
- if (idx != -1) {
- typeContainerName= fullTypeName.substring(0, idx);
- typeName= fullTypeName.substring(idx + 1);
- } else {
- typeContainerName= ""; //$NON-NLS-1$
- typeName= fullTypeName;
- }
-
- if (typeContainerName.length() == 0 && PrimitiveType.toCode(typeName) != null) {
- return fullTypeName;
- }
-
- if (context == null)
- context= this.defaultContext;
-
- int res= context.findInContext(typeContainerName, typeName, ImportRewriteContext.KIND_TYPE);
- if (res == ImportRewriteContext.RES_NAME_CONFLICT) {
- return fullTypeName;
- }
- if (res == ImportRewriteContext.RES_NAME_UNKNOWN) {
- addEntry(NORMAL_PREFIX + fullTypeName);
- }
- if (res == ImportRewriteContext.RES_NAME_UNKNOWN_NEEDS_EXPLICIT_IMPORT) {
- addEntry(NORMAL_PREFIX + fullTypeName);
- this.typeExplicitSimpleNames.add(typeName);
- }
- return typeName;
- }
-
- private void addEntry(String entry) {
- this.existingImports.add(entry);
-
- this.addedImports.add(entry);
- }
-
-
-
- /**
- * Returns all non-static imports that are recorded to be added.
- *
- * @return the imports recorded to be added.
- */
- public String[] getAddedImports() {
- return filterFromList(this.addedImports, NORMAL_PREFIX);
- }
-
- /**
- * Returns true if imports have been recorded to be added or removed.
- * @return boolean returns if any changes to imports have been recorded.
- */
- public boolean hasRecordedChanges() {
- return !this.restoreExistingImports
- || !this.addedImports.isEmpty();
- }
-
- private static String[] filterFromList(List imports, char prefix) {
- if (imports == null) {
- return CharOperation.NO_STRINGS;
- }
- List res= new ArrayList<>();
- for (String curr : imports) {
- if (prefix == curr.charAt(0)) {
- res.add(curr.substring(1));
- }
- }
- return res.toArray(new String[res.size()]);
- }
-
-
- /**
- * Reads the positions of each existing import declaration along with any associated comments,
- * and returns these in a list whose iteration order reflects the existing order of the imports
- * in the compilation unit.
- */
- private int getAddedImportsInsertLocation() {
- List importDeclarations = astRoot.imports();
-
- if (importDeclarations == null) {
- importDeclarations = Collections.emptyList();
- }
-
- List comments = astRoot.getCommentList();
-
- int currentCommentIndex = 0;
-
- // Skip over package and file header comments (see https://bugs.eclipse.org/121428).
- ImportDeclaration firstImport = importDeclarations.get(0);
- PackageDeclaration packageDeclaration = astRoot.getPackage();
- int firstImportStartPosition = packageDeclaration == null
- ? firstImport.getStartPosition()
- : astRoot.getExtendedStartPosition(packageDeclaration)
- + astRoot.getExtendedLength(packageDeclaration);
- while (currentCommentIndex < comments.size()
- && comments.get(currentCommentIndex).getStartPosition() < firstImportStartPosition) {
- currentCommentIndex++;
- }
-
- int previousExtendedEndPosition = -1;
- for (ImportDeclaration currentImport : importDeclarations) {
- int extendedEndPosition = astRoot.getExtendedStartPosition(currentImport)
- + astRoot.getExtendedLength(currentImport);
-
- int commentAfterImportIndex = currentCommentIndex;
- while (commentAfterImportIndex < comments.size()
- && comments.get(commentAfterImportIndex).getStartPosition() < extendedEndPosition) {
- commentAfterImportIndex++;
- }
-
-
- currentCommentIndex = commentAfterImportIndex;
- previousExtendedEndPosition = extendedEndPosition;
- }
-
- return previousExtendedEndPosition;
- }
-
- public DocumentEdits createEdit(IDocument doc) {
- DocumentEdits edits = null;
- StringBuffer buffer = new StringBuffer();
-
- String[] createdImprts = getAddedImports();
- if (createdImprts != null && createdImprts.length >0) {
- edits =new DocumentEdits(doc, false);
- buffer.append('\n');
- for (String imp : createdImprts) {
- buffer.append("import ");
- buffer.append(imp);
- buffer.append(';');
- buffer.append('\n');
- }
- edits.insert(getAddedImportsInsertLocation(), buffer.toString());
-
- }
- return edits;
- }
-}
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/DefaultJavaElementLocationProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/DefaultJavaElementLocationProvider.java
index bb7927fea..4bdeb4efe 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/DefaultJavaElementLocationProvider.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/DefaultJavaElementLocationProvider.java
@@ -15,24 +15,14 @@ import java.net.URL;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
-import org.eclipse.jdt.core.dom.ASTVisitor;
-import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
-import org.eclipse.jdt.core.dom.EnumDeclaration;
-import org.eclipse.jdt.core.dom.MethodDeclaration;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.boot.java.utils.ORCompilationUnitCache;
-import org.springframework.ide.vscode.commons.java.IField;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.java.IMember;
-import org.springframework.ide.vscode.commons.java.IMethod;
-import org.springframework.ide.vscode.commons.java.IType;
-import org.springframework.ide.vscode.commons.util.text.TextDocument;
public class DefaultJavaElementLocationProvider implements JavaElementLocationProvider {
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/BeanInjectedIntoHoverProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/BeanInjectedIntoHoverProvider.java
index 3a2a69520..37e7c8a6d 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/BeanInjectedIntoHoverProvider.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/BeanInjectedIntoHoverProvider.java
@@ -14,7 +14,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Optional;
-import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.lsp4j.CodeLens;
import org.eclipse.lsp4j.Hover;
import org.eclipse.lsp4j.Range;
@@ -28,7 +27,6 @@ import org.springframework.ide.vscode.boot.java.autowired.AutowiredHoverProvider
import org.springframework.ide.vscode.boot.java.links.SourceLinks;
import org.springframework.ide.vscode.boot.java.livehover.v2.LiveBean;
import org.springframework.ide.vscode.boot.java.livehover.v2.SpringProcessLiveData;
-import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.util.Optionals;
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/LiveHoverUtils.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/LiveHoverUtils.java
index a507195fc..e6df47b3d 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/LiveHoverUtils.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/LiveHoverUtils.java
@@ -19,7 +19,6 @@ import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.lsp4j.CodeLens;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.Range;
@@ -33,7 +32,6 @@ import org.springframework.ide.vscode.boot.java.links.SourceLinks;
import org.springframework.ide.vscode.boot.java.livehover.v2.LiveBean;
import org.springframework.ide.vscode.boot.java.livehover.v2.LiveBeansModel;
import org.springframework.ide.vscode.boot.java.livehover.v2.SpringProcessLiveData;
-import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
import org.springframework.ide.vscode.boot.java.utils.SpringResource;
import org.springframework.ide.vscode.commons.java.IJavaProject;
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java
deleted file mode 100644
index 2e792c8a7..000000000
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*******************************************************************************
- * 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
- * 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.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
-
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.Annotation;
-import org.eclipse.jdt.core.dom.ArrayInitializer;
-import org.eclipse.jdt.core.dom.Expression;
-import org.eclipse.jdt.core.dom.IBinding;
-import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.IVariableBinding;
-import org.eclipse.jdt.core.dom.MemberValuePair;
-import org.eclipse.jdt.core.dom.MethodDeclaration;
-import org.eclipse.jdt.core.dom.Name;
-import org.eclipse.jdt.core.dom.NormalAnnotation;
-import org.eclipse.jdt.core.dom.QualifiedName;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
-import org.eclipse.jdt.core.dom.StringLiteral;
-import org.eclipse.jdt.core.dom.TypeDeclaration;
-import org.eclipse.lsp4j.Range;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.ide.vscode.boot.java.Annotations;
-import org.springframework.ide.vscode.commons.util.CollectorUtil;
-import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
-import org.springframework.ide.vscode.commons.util.text.TextDocument;
-
-import com.google.common.collect.ImmutableList;
-
-public class ASTUtils {
-
- private static final Logger log = LoggerFactory.getLogger(ASTUtils.class);
-
- public static DocumentRegion nameRegion(TextDocument doc, Annotation annotation) {
- int start = annotation.getTypeName().getStartPosition();
- int end = start + annotation.getTypeName().getLength();
- if (doc.getSafeChar(start - 1) == '@') {
- start--;
- }
- return new DocumentRegion(doc, start, end);
- }
-
- public static Optional nameRange(TextDocument doc, Annotation annotation) {
- try {
- return Optional.of(nameRegion(doc, annotation).asRange());
- } catch (Exception e) {
- log.error("", e);
- return Optional.empty();
- }
- }
-
- public static DocumentRegion stringRegion(TextDocument doc, StringLiteral node) {
- DocumentRegion nodeRegion = nodeRegion(doc, node);
- if (nodeRegion.startsWith("\"")) {
- nodeRegion = nodeRegion.subSequence(1);
- }
- if (nodeRegion.endsWith("\"")) {
- nodeRegion = nodeRegion.subSequence(0, nodeRegion.getLength()-1);
- }
- return nodeRegion;
- }
-
-
- public static DocumentRegion nodeRegion(TextDocument doc, ASTNode node) {
- int start = node.getStartPosition();
- int end = start + node.getLength();
- return new DocumentRegion(doc, start, end);
- }
-
- public static Optional getAttribute(Annotation annotation, String name) {
- if (annotation != null) {
- try {
- if (annotation.isSingleMemberAnnotation() && name.equals("value")) {
- SingleMemberAnnotation sma = (SingleMemberAnnotation) annotation;
- return Optional.ofNullable(sma.getValue());
- } else if (annotation.isNormalAnnotation()) {
- NormalAnnotation na = (NormalAnnotation) annotation;
- Object attributeObjs = na.getStructuralProperty(NormalAnnotation.VALUES_PROPERTY);
- if (attributeObjs instanceof List) {
- for (Object atrObj : (List>)attributeObjs) {
- if (atrObj instanceof MemberValuePair) {
- MemberValuePair mvPair = (MemberValuePair) atrObj;
- if (name.equals(mvPair.getName().getIdentifier())) {
- return Optional.ofNullable(mvPair.getValue());
- }
- }
- }
- }
- }
- } catch (Exception e) {
- log.error("", e);
- }
- }
- return Optional.empty();
- }
-
- /**
- * For case where a expression can be either a String or a array of Strings and
- * we are interested in the first element of the array. (I.e. typical case
- * when annotation attribute is of type String[] (because Java allows using a single
- * value as a convenient syntax for writing an array of length 1 in that case.
- */
- public static Optional getFirstString(Expression exp) {
- if (exp instanceof StringLiteral) {
- return Optional.ofNullable(getLiteralValue((StringLiteral) exp));
- } else if (exp instanceof ArrayInitializer) {
- ArrayInitializer array = (ArrayInitializer) exp;
- Object objs = array.getStructuralProperty(ArrayInitializer.EXPRESSIONS_PROPERTY);
- if (objs instanceof List) {
- List> list = (List>) objs;
- if (!list.isEmpty()) {
- Object firstObj = list.get(0);
- if (firstObj instanceof Expression) {
- return getFirstString((Expression) firstObj);
- }
- }
- }
- }
- return Optional.empty();
- }
-
- public static TypeDeclaration findDeclaringType(ASTNode node) {
- while (node != null && !(node instanceof TypeDeclaration)) {
- node = node.getParent();
- }
-
- return node != null ? (TypeDeclaration) node : null;
- }
-
- public static boolean hasExactlyOneConstructor(TypeDeclaration typeDecl) {
- boolean oneFound = false;
- MethodDeclaration[] methods = typeDecl.getMethods();
- for (MethodDeclaration methodDeclaration : methods) {
- if (methodDeclaration.isConstructor()) {
- if (oneFound) {
- return false;
- } else {
- oneFound = true;
- }
- }
- }
- return oneFound;
- }
-
- public static MethodDeclaration getAnnotatedMethod(Annotation annotation) {
- ASTNode parent = annotation.getParent();
- if (parent instanceof MethodDeclaration) {
- return (MethodDeclaration)parent;
- }
- return null;
- }
-
- public static TypeDeclaration getAnnotatedType(Annotation annotation) {
- ASTNode parent = annotation.getParent();
- if (parent instanceof TypeDeclaration) {
- return (TypeDeclaration)parent;
- }
- return null;
- }
-
- public static String getLiteralValue(StringLiteral node) {
- synchronized (node.getAST()) {
- return node.getLiteralValue();
- }
- }
-
- public static String getExpressionValueAsString(Expression exp, Consumer dependencies) {
- if (exp instanceof StringLiteral) {
- return getLiteralValue((StringLiteral) exp);
- } else if (exp instanceof Name) {
- IBinding binding = ((Name) exp).resolveBinding();
- if (binding != null && binding.getKind() == IBinding.VARIABLE) {
- IVariableBinding varBinding = (IVariableBinding) binding;
- ITypeBinding klass = varBinding.getDeclaringClass();
- if (klass!=null) {
- dependencies.accept(klass);
-
-
- }
- Object constValue = varBinding.getConstantValue();
- if (constValue != null) {
- return constValue.toString();
- }
- }
- if (exp instanceof QualifiedName) {
- return getExpressionValueAsString(((QualifiedName) exp).getName(), dependencies);
- }
- else if (exp instanceof SimpleName) {
- return ((SimpleName) exp).getIdentifier();
- }
- else {
- return null;
- }
- } else {
- return null;
- }
- }
-
- @SuppressWarnings("unchecked")
- public static String[] getExpressionValueAsArray(Expression exp, Consumer dependencies) {
- if (exp instanceof ArrayInitializer) {
- ArrayInitializer array = (ArrayInitializer) exp;
- return ((List) array.expressions()).stream().map(e -> getExpressionValueAsString(e, dependencies))
- .filter(Objects::nonNull).toArray(String[]::new);
- } else {
- String rm = getExpressionValueAsString(exp, dependencies);
- if (rm != null) {
- return new String[] { rm };
- }
- }
- return null;
- }
-
- @SuppressWarnings("unchecked")
- public static List getExpressionValueAsListOfLiterals(Expression exp) {
- if (exp instanceof ArrayInitializer) {
- ArrayInitializer array = (ArrayInitializer) exp;
- return ((List) array.expressions()).stream()
- .flatMap(e -> e instanceof StringLiteral
- ? Stream.of((StringLiteral)e)
- : Stream.empty()
- )
- .collect(CollectorUtil.toImmutableList());
- } else if (exp instanceof StringLiteral){
- return ImmutableList.of((StringLiteral)exp);
- }
- return ImmutableList.of();
- }
-
-
- public static Collection getAnnotations(TypeDeclaration declaringType) {
- Object modifiersObj = declaringType.getStructuralProperty(TypeDeclaration.MODIFIERS2_PROPERTY);
- if (modifiersObj instanceof List) {
- ImmutableList.Builder annotations = ImmutableList.builder();
- for (Object node : (List>)modifiersObj) {
- if (node instanceof Annotation) {
- annotations.add((Annotation) node);
- }
- }
- return annotations.build();
- }
- return ImmutableList.of();
- }
-
-
- public static String getAnnotationType(Annotation annotation) {
- ITypeBinding binding = annotation.resolveTypeBinding();
- if (binding!=null) {
- return binding.getQualifiedName();
- }
- return null;
- }
-
- public static Optional beanId(List