feat: Improve the user experience of new Java file. (#801)
This commit is contained in:
Родитель
69268d938c
Коммит
a0dcf41bca
|
@ -13,6 +13,7 @@ This project incorporates components from the projects listed below. The origina
|
||||||
6. jprichardson/node-fs-extra (https://github.com/jprichardson/node-fs-extra)
|
6. jprichardson/node-fs-extra (https://github.com/jprichardson/node-fs-extra)
|
||||||
7. lodash/lodash (https://github.com/lodash/lodash)
|
7. lodash/lodash (https://github.com/lodash/lodash)
|
||||||
8. sindresorhus/globby (https://github.com/sindresorhus/globby)
|
8. sindresorhus/globby (https://github.com/sindresorhus/globby)
|
||||||
|
9. tcort/fmtr (https://github.com/tcort/fmtr)
|
||||||
|
|
||||||
%% Apache Commons Lang NOTICES AND INFORMATION BEGIN HERE
|
%% Apache Commons Lang NOTICES AND INFORMATION BEGIN HERE
|
||||||
=========================================
|
=========================================
|
||||||
|
@ -571,3 +572,15 @@ The above copyright notice and this permission notice shall be included in all c
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
=========================================
|
=========================================
|
||||||
END OF sindresorhus/globby NOTICES AND INFORMATION
|
END OF sindresorhus/globby NOTICES AND INFORMATION
|
||||||
|
|
||||||
|
%% tcort/fmtr NOTICES AND INFORMATION BEGIN HERE
|
||||||
|
=========================================
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (c) 2015-2021 Thomas Cort linuxgeek@gmail.com
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
=========================================
|
||||||
|
END OF tcort/fmtr NOTICES AND INFORMATION
|
||||||
|
|
|
@ -36,6 +36,8 @@ import org.eclipse.jdt.core.IPackageFragmentRoot;
|
||||||
import org.eclipse.jdt.core.IType;
|
import org.eclipse.jdt.core.IType;
|
||||||
import org.eclipse.jdt.core.JavaCore;
|
import org.eclipse.jdt.core.JavaCore;
|
||||||
import org.eclipse.jdt.core.JavaModelException;
|
import org.eclipse.jdt.core.JavaModelException;
|
||||||
|
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
|
||||||
|
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
|
||||||
import org.eclipse.jdt.internal.core.JrtPackageFragmentRoot;
|
import org.eclipse.jdt.internal.core.JrtPackageFragmentRoot;
|
||||||
import org.eclipse.jdt.ls.core.internal.JDTUtils;
|
import org.eclipse.jdt.ls.core.internal.JDTUtils;
|
||||||
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
|
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
|
||||||
|
@ -68,9 +70,11 @@ public class PackageNode {
|
||||||
public static final String REFERENCED_LIBRARIES_PATH = "REFERENCED_LIBRARIES_PATH";
|
public static final String REFERENCED_LIBRARIES_PATH = "REFERENCED_LIBRARIES_PATH";
|
||||||
private static final String REFERENCED_LIBRARIES_CONTAINER_NAME = "Referenced Libraries";
|
private static final String REFERENCED_LIBRARIES_CONTAINER_NAME = "Referenced Libraries";
|
||||||
private static final String IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER_NAME = "Referenced Libraries (Read-only)";
|
private static final String IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER_NAME = "Referenced Libraries (Read-only)";
|
||||||
public static final ContainerNode REFERENCED_LIBRARIES_CONTAINER = new ContainerNode(REFERENCED_LIBRARIES_CONTAINER_NAME, REFERENCED_LIBRARIES_PATH,
|
public static final ContainerNode REFERENCED_LIBRARIES_CONTAINER = new ContainerNode(
|
||||||
|
REFERENCED_LIBRARIES_CONTAINER_NAME, REFERENCED_LIBRARIES_PATH,
|
||||||
NodeKind.CONTAINER, IClasspathEntry.CPE_CONTAINER);
|
NodeKind.CONTAINER, IClasspathEntry.CPE_CONTAINER);
|
||||||
public static final ContainerNode IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER = new ContainerNode(IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER_NAME,
|
public static final ContainerNode IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER = new ContainerNode(
|
||||||
|
IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER_NAME,
|
||||||
REFERENCED_LIBRARIES_PATH, NodeKind.CONTAINER, IClasspathEntry.CPE_CONTAINER);
|
REFERENCED_LIBRARIES_PATH, NodeKind.CONTAINER, IClasspathEntry.CPE_CONTAINER);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,6 +89,8 @@ public class PackageNode {
|
||||||
*/
|
*/
|
||||||
private static final String UNMANAGED_FOLDER_NATURE_ID = "org.eclipse.jdt.ls.core.unmanagedFolder";
|
private static final String UNMANAGED_FOLDER_NATURE_ID = "org.eclipse.jdt.ls.core.unmanagedFolder";
|
||||||
|
|
||||||
|
private static final String MAX_SOURCE_VERSION = "MaxSourceVersion";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the PackageNode.
|
* The name of the PackageNode.
|
||||||
*/
|
*/
|
||||||
|
@ -164,7 +170,8 @@ public class PackageNode {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
IProject proj = javaElement.getJavaProject().getProject();
|
IProject proj = javaElement.getJavaProject().getProject();
|
||||||
PackageNode projectNode = new PackageNode(proj.getName(), proj.getFullPath().toPortableString(), NodeKind.PROJECT);
|
PackageNode projectNode = new PackageNode(proj.getName(), proj.getFullPath().toPortableString(),
|
||||||
|
NodeKind.PROJECT);
|
||||||
projectNode.setUri(ProjectUtils.getProjectRealFolder(proj).toFile().toURI().toString());
|
projectNode.setUri(ProjectUtils.getProjectRealFolder(proj).toFile().toURI().toString());
|
||||||
try {
|
try {
|
||||||
List<String> natureIds = new ArrayList<>(Arrays.asList(proj.getDescription().getNatureIds()));
|
List<String> natureIds = new ArrayList<>(Arrays.asList(proj.getDescription().getNatureIds()));
|
||||||
|
@ -173,6 +180,10 @@ public class PackageNode {
|
||||||
projectNode.setMetaDataValue(UNMANAGED_FOLDER_INNER_PATH, proj.getLocationURI().toString());
|
projectNode.setMetaDataValue(UNMANAGED_FOLDER_INNER_PATH, proj.getLocationURI().toString());
|
||||||
}
|
}
|
||||||
projectNode.setMetaDataValue(NATURE_ID, natureIds);
|
projectNode.setMetaDataValue(NATURE_ID, natureIds);
|
||||||
|
String sourceVersion = javaElement.getJavaProject().getOption(JavaCore.COMPILER_SOURCE, true);
|
||||||
|
int jdkLevel = (int) (CompilerOptions.versionToJdkLevel(sourceVersion, true) >>> 16);
|
||||||
|
int majorVersion = Math.max(0, jdkLevel - ClassFileConstants.MAJOR_VERSION_0);
|
||||||
|
projectNode.setMetaDataValue(MAX_SOURCE_VERSION, majorVersion);
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -201,7 +212,8 @@ public class PackageNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PackageNode createNodeForPackageFragment(IPackageFragment packageFragment) {
|
public static PackageNode createNodeForPackageFragment(IPackageFragment packageFragment) {
|
||||||
PackageNode fragmentNode = new PackageNode(packageFragment.getElementName(), packageFragment.getPath().toPortableString(), NodeKind.PACKAGE);
|
PackageNode fragmentNode = new PackageNode(packageFragment.getElementName(),
|
||||||
|
packageFragment.getPath().toPortableString(), NodeKind.PACKAGE);
|
||||||
fragmentNode.setHandlerIdentifier(packageFragment.getHandleIdentifier());
|
fragmentNode.setHandlerIdentifier(packageFragment.getHandleIdentifier());
|
||||||
if (packageFragment.getResource() != null) {
|
if (packageFragment.getResource() != null) {
|
||||||
fragmentNode.setUri(packageFragment.getResource().getLocationURI().toString());
|
fragmentNode.setUri(packageFragment.getResource().getLocationURI().toString());
|
||||||
|
@ -215,16 +227,19 @@ public class PackageNode {
|
||||||
IClasspathEntry entry = pkgRoot.getRawClasspathEntry();
|
IClasspathEntry entry = pkgRoot.getRawClasspathEntry();
|
||||||
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), pkgRoot.getJavaProject());
|
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), pkgRoot.getJavaProject());
|
||||||
PackageNode containerNode = null;
|
PackageNode containerNode = null;
|
||||||
if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
|
if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY
|
||||||
|
|| entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
|
||||||
containerNode = REFERENCED_LIBRARIES_CONTAINER;
|
containerNode = REFERENCED_LIBRARIES_CONTAINER;
|
||||||
} else {
|
} else {
|
||||||
containerNode = new ContainerNode(container.getDescription(), container.getPath().toPortableString(), NodeKind.CONTAINER, entry.getEntryKind());
|
containerNode = new ContainerNode(container.getDescription(), container.getPath().toPortableString(),
|
||||||
|
NodeKind.CONTAINER, entry.getEntryKind());
|
||||||
}
|
}
|
||||||
return containerNode;
|
return containerNode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PackageRootNode createNodeForPackageFragmentRoot(IPackageFragmentRoot pkgRoot) throws JavaModelException {
|
public static PackageRootNode createNodeForPackageFragmentRoot(IPackageFragmentRoot pkgRoot)
|
||||||
|
throws JavaModelException {
|
||||||
PackageRootNode node;
|
PackageRootNode node;
|
||||||
String displayName = pkgRoot.getElementName();
|
String displayName = pkgRoot.getElementName();
|
||||||
boolean isSourcePath = pkgRoot.getKind() == IPackageFragmentRoot.K_SOURCE;
|
boolean isSourcePath = pkgRoot.getKind() == IPackageFragmentRoot.K_SOURCE;
|
||||||
|
@ -275,10 +290,12 @@ public class PackageNode {
|
||||||
* @param javaProject
|
* @param javaProject
|
||||||
* correspond java project
|
* correspond java project
|
||||||
* @param nodeKind
|
* @param nodeKind
|
||||||
* could be CONTAINER or PACKAGEROOT(for referenced libraries)
|
* could be CONTAINER or PACKAGEROOT(for referenced
|
||||||
|
* libraries)
|
||||||
* @return correspond PackageNode of classpath entry
|
* @return correspond PackageNode of classpath entry
|
||||||
*/
|
*/
|
||||||
public static PackageNode createNodeForClasspathEntry(IClasspathEntry classpathEntry, IJavaProject javaProject, NodeKind nodeKind) {
|
public static PackageNode createNodeForClasspathEntry(IClasspathEntry classpathEntry, IJavaProject javaProject,
|
||||||
|
NodeKind nodeKind) {
|
||||||
try {
|
try {
|
||||||
IClasspathEntry entry = JavaCore.getResolvedClasspathEntry(classpathEntry);
|
IClasspathEntry entry = JavaCore.getResolvedClasspathEntry(classpathEntry);
|
||||||
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
|
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
|
||||||
|
@ -289,7 +306,8 @@ public class PackageNode {
|
||||||
if (container != null) {
|
if (container != null) {
|
||||||
PackageNode node = null;
|
PackageNode node = null;
|
||||||
if (nodeKind == NodeKind.CONTAINER) {
|
if (nodeKind == NodeKind.CONTAINER) {
|
||||||
node = new ContainerNode(container.getDescription(), container.getPath().toPortableString(), nodeKind, entry.getEntryKind());
|
node = new ContainerNode(container.getDescription(), container.getPath().toPortableString(),
|
||||||
|
nodeKind, entry.getEntryKind());
|
||||||
final URI containerURI = ExtUtils.getContainerURI(javaProject, container);
|
final URI containerURI = ExtUtils.getContainerURI(javaProject, container);
|
||||||
node.setUri(containerURI != null ? containerURI.toString() : null);
|
node.setUri(containerURI != null ? containerURI.toString() : null);
|
||||||
} else if (nodeKind == NodeKind.PACKAGEROOT) { // ClasspathEntry for referenced jar files
|
} else if (nodeKind == NodeKind.PACKAGEROOT) { // ClasspathEntry for referenced jar files
|
||||||
|
@ -310,7 +328,8 @@ public class PackageNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PackageNode createNodeForPrimaryType(IType type) {
|
public static PackageNode createNodeForPrimaryType(IType type) {
|
||||||
PackageNode primaryTypeNode = new PackageNode(type.getElementName(), type.getPath().toPortableString(), NodeKind.PRIMARYTYPE);
|
PackageNode primaryTypeNode = new PackageNode(type.getElementName(), type.getPath().toPortableString(),
|
||||||
|
NodeKind.PRIMARYTYPE);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (type.isEnum()) {
|
if (type.isEnum()) {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"await-lock": "^2.2.2",
|
"await-lock": "^2.2.2",
|
||||||
|
"fmtr": "^1.1.4",
|
||||||
"fs-extra": "^10.1.0",
|
"fs-extra": "^10.1.0",
|
||||||
"globby": "^13.1.3",
|
"globby": "^13.1.3",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
@ -2052,6 +2053,14 @@
|
||||||
"flat": "cli.js"
|
"flat": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fmtr": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/fmtr/-/fmtr-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-5qCv7eLlkR7LUDrcQdx0vGFo8tLgwFtO0JHkX9xfQm+DNnXpk9zQNSIldKlZ2VPZBwxTM9GB1esyeQuxhCVvmQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.21"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.15.3",
|
"version": "1.15.3",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
||||||
|
@ -6879,6 +6888,14 @@
|
||||||
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
|
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"fmtr": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/fmtr/-/fmtr-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-5qCv7eLlkR7LUDrcQdx0vGFo8tLgwFtO0JHkX9xfQm+DNnXpk9zQNSIldKlZ2VPZBwxTM9GB1esyeQuxhCVvmQ==",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.17.21"
|
||||||
|
}
|
||||||
|
},
|
||||||
"follow-redirects": {
|
"follow-redirects": {
|
||||||
"version": "1.15.3",
|
"version": "1.15.3",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
||||||
|
|
84
package.json
84
package.json
|
@ -192,6 +192,36 @@
|
||||||
"category": "Java",
|
"category": "Java",
|
||||||
"icon": "$(add)"
|
"icon": "$(add)"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaInterface",
|
||||||
|
"title": "%contributes.commands.java.view.package.newJavaInterface%",
|
||||||
|
"category": "Java",
|
||||||
|
"icon": "$(add)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaEnum",
|
||||||
|
"title": "%contributes.commands.java.view.package.newJavaEnum%",
|
||||||
|
"category": "Java",
|
||||||
|
"icon": "$(add)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaRecord",
|
||||||
|
"title": "%contributes.commands.java.view.package.newJavaRecord%",
|
||||||
|
"category": "Java",
|
||||||
|
"icon": "$(add)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaAnnotation",
|
||||||
|
"title": "%contributes.commands.java.view.package.newJavaAnnotation%",
|
||||||
|
"category": "Java",
|
||||||
|
"icon": "$(add)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaAbstractClass",
|
||||||
|
"title": "%contributes.commands.java.view.package.newJavaAbstractClass%",
|
||||||
|
"category": "Java",
|
||||||
|
"icon": "$(add)"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "java.view.package.newPackage",
|
"command": "java.view.package.newPackage",
|
||||||
"title": "%contributes.commands.java.view.package.newPackage%",
|
"title": "%contributes.commands.java.view.package.newPackage%",
|
||||||
|
@ -395,6 +425,26 @@
|
||||||
"command": "java.view.package.newJavaClass",
|
"command": "java.view.package.newJavaClass",
|
||||||
"when": "false"
|
"when": "false"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaInterface",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaEnum",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaRecord",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaAnnotation",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaAbstractClass",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "java.view.package.newPackage",
|
"command": "java.view.package.newPackage",
|
||||||
"when": "false"
|
"when": "false"
|
||||||
|
@ -641,21 +691,46 @@
|
||||||
"javaProject.new": [
|
"javaProject.new": [
|
||||||
{
|
{
|
||||||
"command": "java.view.package.newJavaClass",
|
"command": "java.view.package.newJavaClass",
|
||||||
"group": "new@10",
|
"group": "new1@10",
|
||||||
|
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaInterface",
|
||||||
|
"group": "new1@11",
|
||||||
|
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaEnum",
|
||||||
|
"group": "new1@12",
|
||||||
|
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaRecord",
|
||||||
|
"group": "new1@13",
|
||||||
|
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/) && viewItem =~ /java:.*\\+allowRecord\\b/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaAnnotation",
|
||||||
|
"group": "new1@14",
|
||||||
|
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "java.view.package.newJavaAbstractClass",
|
||||||
|
"group": "new1@15",
|
||||||
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
|
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "java.view.package.newPackage",
|
"command": "java.view.package.newPackage",
|
||||||
"group": "new@20",
|
"group": "new1@20",
|
||||||
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
|
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "java.view.package.newFile",
|
"command": "java.view.package.newFile",
|
||||||
"group": "new@30"
|
"group": "new2@30"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "java.view.package.newFolder",
|
"command": "java.view.package.newFolder",
|
||||||
"group": "new@40",
|
"group": "new2@40",
|
||||||
"when": "view == javaProjectExplorer && (viewItem =~ /java:(file|folder|project)/ || viewItem =~ /java:(packageRoot)(?=.*?\\b\\+resource\\b)/)"
|
"when": "view == javaProjectExplorer && (viewItem =~ /java:(file|folder|project)/ || viewItem =~ /java:(packageRoot)(?=.*?\\b\\+resource\\b)/)"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -895,6 +970,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"await-lock": "^2.2.2",
|
"await-lock": "^2.2.2",
|
||||||
|
"fmtr": "^1.1.4",
|
||||||
"fs-extra": "^10.1.0",
|
"fs-extra": "^10.1.0",
|
||||||
"globby": "^13.1.3",
|
"globby": "^13.1.3",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
|
|
@ -22,10 +22,15 @@
|
||||||
"contributes.commands.java.view.package.copyFilePath": "Copy Path",
|
"contributes.commands.java.view.package.copyFilePath": "Copy Path",
|
||||||
"contributes.commands.java.view.package.copyRelativeFilePath": "Copy Relative Path",
|
"contributes.commands.java.view.package.copyRelativeFilePath": "Copy Relative Path",
|
||||||
"contributes.commands.java.view.package.new": "New...",
|
"contributes.commands.java.view.package.new": "New...",
|
||||||
"contributes.commands.java.view.package.newJavaClass": "Java Class...",
|
"contributes.commands.java.view.package.newJavaClass": "Class...",
|
||||||
|
"contributes.commands.java.view.package.newJavaInterface": "Interface...",
|
||||||
|
"contributes.commands.java.view.package.newJavaEnum": "Enum...",
|
||||||
|
"contributes.commands.java.view.package.newJavaRecord": "Record...",
|
||||||
|
"contributes.commands.java.view.package.newJavaAnnotation": "Annotation...",
|
||||||
|
"contributes.commands.java.view.package.newJavaAbstractClass": "Abstract Class...",
|
||||||
"contributes.commands.java.view.package.newPackage": "Package...",
|
"contributes.commands.java.view.package.newPackage": "Package...",
|
||||||
"contributes.commands.java.view.package.newFile": "File...",
|
"contributes.commands.java.view.package.newFile": "File...",
|
||||||
"contributes.commands.java.view.package.newFolder": "Folder",
|
"contributes.commands.java.view.package.newFolder": "Folder...",
|
||||||
"contributes.commands.java.view.package.renameFile": "Rename",
|
"contributes.commands.java.view.package.renameFile": "Rename",
|
||||||
"contributes.commands.java.view.package.moveFileToTrash": "Delete",
|
"contributes.commands.java.view.package.moveFileToTrash": "Delete",
|
||||||
"contributes.commands.java.view.package.deleteFilePermanently": "Delete Permanently",
|
"contributes.commands.java.view.package.deleteFilePermanently": "Delete Permanently",
|
||||||
|
|
|
@ -22,10 +22,15 @@
|
||||||
"contributes.commands.java.view.package.copyFilePath": "复制路径",
|
"contributes.commands.java.view.package.copyFilePath": "复制路径",
|
||||||
"contributes.commands.java.view.package.copyRelativeFilePath": "复制相对路径",
|
"contributes.commands.java.view.package.copyRelativeFilePath": "复制相对路径",
|
||||||
"contributes.commands.java.view.package.new": "创建...",
|
"contributes.commands.java.view.package.new": "创建...",
|
||||||
"contributes.commands.java.view.package.newJavaClass": "Java 类...",
|
"contributes.commands.java.view.package.newJavaClass": "类...",
|
||||||
|
"contributes.commands.java.view.package.newJavaInterface": "接口类型...",
|
||||||
|
"contributes.commands.java.view.package.newJavaEnum": "枚举类型...",
|
||||||
|
"contributes.commands.java.view.package.newJavaRecord": "记录类型...",
|
||||||
|
"contributes.commands.java.view.package.newJavaAnnotation": "注解类型...",
|
||||||
|
"contributes.commands.java.view.package.newJavaAbstractClass": "抽象类型...",
|
||||||
"contributes.commands.java.view.package.newPackage": "包...",
|
"contributes.commands.java.view.package.newPackage": "包...",
|
||||||
"contributes.commands.java.view.package.newFile": "文件...",
|
"contributes.commands.java.view.package.newFile": "文件...",
|
||||||
"contributes.commands.java.view.package.newFolder": "文件夹",
|
"contributes.commands.java.view.package.newFolder": "文件夹...",
|
||||||
"contributes.commands.java.view.package.renameFile": "重命名",
|
"contributes.commands.java.view.package.renameFile": "重命名",
|
||||||
"contributes.commands.java.view.package.moveFileToTrash": "删除",
|
"contributes.commands.java.view.package.moveFileToTrash": "删除",
|
||||||
"contributes.commands.java.view.package.deleteFilePermanently": "永久删除",
|
"contributes.commands.java.view.package.deleteFilePermanently": "永久删除",
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
"contributes.commands.java.view.package.copyFilePath": "複製路徑",
|
"contributes.commands.java.view.package.copyFilePath": "複製路徑",
|
||||||
"contributes.commands.java.view.package.copyRelativeFilePath": "複製相對路徑",
|
"contributes.commands.java.view.package.copyRelativeFilePath": "複製相對路徑",
|
||||||
"contributes.commands.java.view.package.new": "建立...",
|
"contributes.commands.java.view.package.new": "建立...",
|
||||||
"contributes.commands.java.view.package.newJavaClass": "Java 類別...",
|
"contributes.commands.java.view.package.newJavaClass": "類別...",
|
||||||
"contributes.commands.java.view.package.newPackage": "套件...",
|
"contributes.commands.java.view.package.newPackage": "套件...",
|
||||||
"contributes.commands.java.view.package.newFile": "檔案...",
|
"contributes.commands.java.view.package.newFile": "檔案...",
|
||||||
"contributes.commands.java.view.package.newFolder": "資料夾",
|
"contributes.commands.java.view.package.newFolder": "資料夾...",
|
||||||
"contributes.commands.java.view.package.renameFile": "重新命名",
|
"contributes.commands.java.view.package.renameFile": "重新命名",
|
||||||
"contributes.commands.java.view.package.moveFileToTrash": "刪除",
|
"contributes.commands.java.view.package.moveFileToTrash": "刪除",
|
||||||
"contributes.commands.java.view.package.deleteFilePermanently": "永久刪除",
|
"contributes.commands.java.view.package.deleteFilePermanently": "永久刪除",
|
||||||
|
|
|
@ -42,6 +42,16 @@ export namespace Commands {
|
||||||
|
|
||||||
export const VIEW_PACKAGE_NEW_JAVA_CLASS = "java.view.package.newJavaClass";
|
export const VIEW_PACKAGE_NEW_JAVA_CLASS = "java.view.package.newJavaClass";
|
||||||
|
|
||||||
|
export const VIEW_PACKAGE_NEW_JAVA_INTERFACE = "java.view.package.newJavaInterface";
|
||||||
|
|
||||||
|
export const VIEW_PACKAGE_NEW_JAVA_ENUM = "java.view.package.newJavaEnum";
|
||||||
|
|
||||||
|
export const VIEW_PACKAGE_NEW_JAVA_RECORD = "java.view.package.newJavaRecord";
|
||||||
|
|
||||||
|
export const VIEW_PACKAGE_NEW_JAVA_ANNOTATION = "java.view.package.newJavaAnnotation";
|
||||||
|
|
||||||
|
export const VIEW_PACKAGE_NEW_JAVA_ABSTRACT_CLASS = "java.view.package.newJavaAbstractClass";
|
||||||
|
|
||||||
export const VIEW_PACKAGE_NEW_JAVA_PACKAGE = "java.view.package.newPackage";
|
export const VIEW_PACKAGE_NEW_JAVA_PACKAGE = "java.view.package.newPackage";
|
||||||
|
|
||||||
export const VIEW_PACKAGE_RENAME_FILE = "java.view.package.renameFile";
|
export const VIEW_PACKAGE_RENAME_FILE = "java.view.package.renameFile";
|
||||||
|
@ -133,6 +143,11 @@ export namespace Commands {
|
||||||
export const GET_ALL_PROJECTS = "java.project.getAll";
|
export const GET_ALL_PROJECTS = "java.project.getAll";
|
||||||
|
|
||||||
export const BUILD_PROJECT = "java.project.build";
|
export const BUILD_PROJECT = "java.project.build";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the project settings
|
||||||
|
*/
|
||||||
|
export const GET_PROJECT_SETTINGS = 'java.project.getSettings';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function executeJavaLanguageServerCommand(...rest: any[]) {
|
export function executeJavaLanguageServerCommand(...rest: any[]) {
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
import * as fse from "fs-extra";
|
import * as fse from "fs-extra";
|
||||||
|
import { userInfo } from "os";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import { commands, Extension, extensions, languages, QuickPickItem, SnippetString, TextEditor, Uri,
|
import { commands, Extension, extensions, languages, Position, QuickPickItem, QuickPickItemKind, SnippetString, TextEditor, Uri,
|
||||||
window, workspace, WorkspaceEdit, WorkspaceFolder } from "vscode";
|
window, workspace, WorkspaceEdit, WorkspaceFolder } from "vscode";
|
||||||
import { Commands, PrimaryTypeNode } from "../../extension.bundle";
|
import { Commands, PrimaryTypeNode } from "../../extension.bundle";
|
||||||
import { ExtensionName } from "../constants";
|
import { ExtensionName } from "../constants";
|
||||||
|
@ -13,26 +14,87 @@ import { resourceRoots } from "../views/packageRootNode";
|
||||||
import { checkJavaQualifiedName } from "./utility";
|
import { checkJavaQualifiedName } from "./utility";
|
||||||
import { sendError, setUserError } from "vscode-extension-telemetry-wrapper";
|
import { sendError, setUserError } from "vscode-extension-telemetry-wrapper";
|
||||||
|
|
||||||
|
// tslint:disable no-var-requires
|
||||||
|
const stringInterpolate = require("fmtr");
|
||||||
|
|
||||||
|
export class JavaType {
|
||||||
|
public static readonly CLASS: JavaType = new JavaType("Class", "class", "$(symbol-class)");
|
||||||
|
public static readonly INTERFACE: JavaType = new JavaType("Interface", "interface", "$(symbol-interface)");
|
||||||
|
public static readonly ENUM: JavaType = new JavaType("Enum", "enum", "$(symbol-enum)");
|
||||||
|
public static readonly RECORD: JavaType = new JavaType("Record", "record", "$(symbol-class)");
|
||||||
|
public static readonly ANNOTATION: JavaType = new JavaType("Annotation", "@interface", "$(symbol-interface)");
|
||||||
|
public static readonly ABSTRACT_CLASS: JavaType = new JavaType("Abstract Class", "abstract class", "$(symbol-class)");
|
||||||
|
|
||||||
|
public static readonly ALL: JavaType[] = [
|
||||||
|
JavaType.CLASS,
|
||||||
|
JavaType.INTERFACE,
|
||||||
|
JavaType.ENUM,
|
||||||
|
JavaType.RECORD,
|
||||||
|
JavaType.ANNOTATION,
|
||||||
|
JavaType.ABSTRACT_CLASS,
|
||||||
|
];
|
||||||
|
|
||||||
|
public static fromDisplayName(label: string): JavaType | undefined {
|
||||||
|
if (label?.startsWith("$")) {
|
||||||
|
return JavaType.ALL.find((javaType) => `${javaType.icon} ${javaType.label}` === label);
|
||||||
|
}
|
||||||
|
|
||||||
|
return JavaType.ALL.find((javaType) => javaType.label === label);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getDisplayNames(includeIcon: boolean, includeRecord?: boolean): string[] {
|
||||||
|
return JavaType.ALL
|
||||||
|
.filter((javaType) => includeRecord || javaType !== JavaType.RECORD)
|
||||||
|
.map((javaType) => {
|
||||||
|
if (includeIcon) {
|
||||||
|
return `${javaType.icon} ${javaType.label}`;
|
||||||
|
} else {
|
||||||
|
return javaType.label;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor(public readonly label: string, public readonly keyword: string,
|
||||||
|
public readonly icon: string) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function newResource(node: DataNode): Promise<void> {
|
export async function newResource(node: DataNode): Promise<void> {
|
||||||
const availableTypes: string[] = [];
|
const availableTypes: QuickPickItem[] = [];
|
||||||
// add options for Java nodes
|
// add options for Java nodes
|
||||||
if (node.nodeData.kind === NodeKind.Project ||
|
if (node.nodeData.kind === NodeKind.Project ||
|
||||||
(node.nodeData.kind === NodeKind.PackageRoot && !resourceRoots.includes(node.nodeData.name)) ||
|
(node.nodeData.kind === NodeKind.PackageRoot && !resourceRoots.includes(node.nodeData.name)) ||
|
||||||
node.nodeData.kind === NodeKind.Package ||
|
node.nodeData.kind === NodeKind.Package ||
|
||||||
node.nodeData.kind === NodeKind.PrimaryType ||
|
node.nodeData.kind === NodeKind.PrimaryType ||
|
||||||
node.nodeData.kind === NodeKind.CompilationUnit) {
|
node.nodeData.kind === NodeKind.CompilationUnit) {
|
||||||
availableTypes.push("$(symbol-class) Java Class", "$(symbol-namespace) Package");
|
const allowRecord = node.computeContextValue()?.includes("+allowRecord");
|
||||||
|
availableTypes.push(...JavaType.getDisplayNames(true, allowRecord).map((label) => {
|
||||||
|
return {
|
||||||
|
label,
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
availableTypes.push({
|
||||||
|
label: "$(symbol-namespace) Package",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
availableTypes.push({
|
||||||
|
label: "",
|
||||||
|
kind: QuickPickItemKind.Separator,
|
||||||
|
});
|
||||||
// add new file option
|
// add new file option
|
||||||
availableTypes.push("$(file) File");
|
availableTypes.push({
|
||||||
|
label: "$(file) File",
|
||||||
|
});
|
||||||
|
|
||||||
// add new folder option
|
// add new folder option
|
||||||
if (node.nodeData.kind === NodeKind.Project ||
|
if (node.nodeData.kind === NodeKind.Project ||
|
||||||
(node.nodeData.kind === NodeKind.PackageRoot && resourceRoots.includes(node.nodeData.name)) ||
|
(node.nodeData.kind === NodeKind.PackageRoot && resourceRoots.includes(node.nodeData.name)) ||
|
||||||
node.nodeData.kind === NodeKind.Folder ||
|
node.nodeData.kind === NodeKind.Folder ||
|
||||||
node.nodeData.kind === NodeKind.File) {
|
node.nodeData.kind === NodeKind.File) {
|
||||||
availableTypes.push("$(folder) Folder");
|
availableTypes.push({
|
||||||
|
label: "$(folder) Folder",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = await window.showQuickPick(
|
const type = await window.showQuickPick(
|
||||||
|
@ -43,10 +105,7 @@ export async function newResource(node: DataNode): Promise<void> {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
switch (type) {
|
switch (type?.label) {
|
||||||
case "$(symbol-class) Java Class":
|
|
||||||
await newJavaClass(node);
|
|
||||||
break;
|
|
||||||
case "$(symbol-namespace) Package":
|
case "$(symbol-namespace) Package":
|
||||||
await newPackage(node);
|
await newPackage(node);
|
||||||
break;
|
break;
|
||||||
|
@ -57,23 +116,17 @@ export async function newResource(node: DataNode): Promise<void> {
|
||||||
await newFolder(node);
|
await newFolder(node);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
const javaType = JavaType.fromDisplayName(type?.label || "");
|
||||||
|
if (javaType) {
|
||||||
|
await newJavaFileWithSpecificType(javaType, node);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: separate to two function to handle creation from menu bar and explorer.
|
// Create a new Java file from the menu bar.
|
||||||
export async function newJavaClass(node?: DataNode): Promise<void> {
|
export async function newJavaFile(): Promise<void> {
|
||||||
let packageFsPath: string | undefined;
|
const packageFsPath: string | undefined = await inferPackageFsPath();
|
||||||
if (!node) {
|
|
||||||
packageFsPath = await inferPackageFsPath();
|
|
||||||
} else {
|
|
||||||
if (!node?.uri || !canCreateClass(node)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
packageFsPath = await getPackageFsPath(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packageFsPath === undefined) {
|
if (packageFsPath === undefined) {
|
||||||
// User canceled
|
// User canceled
|
||||||
return;
|
return;
|
||||||
|
@ -81,8 +134,48 @@ export async function newJavaClass(node?: DataNode): Promise<void> {
|
||||||
return newUntitledJavaFile();
|
return newUntitledJavaFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const includeRecord = !(await isVersionLessThan(Uri.file(packageFsPath).toString(), 16));
|
||||||
|
const supportedTypes: string[] = JavaType.getDisplayNames(true, includeRecord);
|
||||||
|
const typeName: string | undefined = await window.showQuickPick(supportedTypes,
|
||||||
|
{
|
||||||
|
placeHolder: "Select the Java type you want to create",
|
||||||
|
ignoreFocusOut: true,
|
||||||
|
});
|
||||||
|
if (!typeName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
newJavaFile0(packageFsPath, JavaType.fromDisplayName(typeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new Java file from the context menu of Java Projects view.
|
||||||
|
export async function newJavaFileWithSpecificType(javaType: JavaType, node?: DataNode): Promise<void> {
|
||||||
|
let packageFsPath: string | undefined;
|
||||||
|
if (!node) {
|
||||||
|
packageFsPath = await inferPackageFsPath();
|
||||||
|
} else {
|
||||||
|
if (!node?.uri || !canCreateClass(node)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
packageFsPath = await getPackageFsPath(node);
|
||||||
|
}
|
||||||
|
if (packageFsPath === undefined) {
|
||||||
|
// User canceled
|
||||||
|
return;
|
||||||
|
} else if (packageFsPath.length === 0) {
|
||||||
|
return newUntitledJavaFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
newJavaFile0(packageFsPath, javaType);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function newJavaFile0(packageFsPath: string, javaType: JavaType | undefined) {
|
||||||
|
if (!javaType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const className: string | undefined = await window.showInputBox({
|
const className: string | undefined = await window.showInputBox({
|
||||||
placeHolder: "Enter the Java file name for class/interface/enum/record/@interface",
|
placeHolder: `Input the ${javaType.label.toLowerCase()} name`,
|
||||||
ignoreFocusOut: true,
|
ignoreFocusOut: true,
|
||||||
validateInput: async (value: string): Promise<string> => {
|
validateInput: async (value: string): Promise<string> => {
|
||||||
const checkMessage: string = checkJavaQualifiedName(value);
|
const checkMessage: string = checkJavaQualifiedName(value);
|
||||||
|
@ -102,12 +195,86 @@ export async function newJavaClass(node?: DataNode): Promise<void> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// `workspace.applyEdit()` will trigger a workspace file event, and let the
|
|
||||||
// vscode-java extension to handle the type: class, interface or enum.
|
|
||||||
const workspaceEdit: WorkspaceEdit = new WorkspaceEdit();
|
|
||||||
const fsPath: string = getNewFilePath(packageFsPath, className);
|
const fsPath: string = getNewFilePath(packageFsPath, className);
|
||||||
workspaceEdit.createFile(Uri.file(fsPath));
|
const packageName = await resolvePackageName(fsPath);
|
||||||
workspace.applyEdit(workspaceEdit);
|
await newJavaFileWithContents(fsPath, javaType, packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// New File implementation is copied from
|
||||||
|
// https://github.com/redhat-developer/vscode-java/blob/86bf3ae02f4f457184e6cc217f20240f9882dde9/src/fileEventHandler.ts#L66
|
||||||
|
async function newJavaFileWithContents(fsPath: string, javaType: JavaType, packageName: string) {
|
||||||
|
const snippets: string[] = [];
|
||||||
|
const formatNumber = (num: number) => num > 9 ? String(num) : `0${num}`;
|
||||||
|
const typeName: string = resolveTypeName(fsPath);
|
||||||
|
const isPackageInfo = typeName === 'package-info';
|
||||||
|
const isModuleInfo = typeName === 'module-info';
|
||||||
|
const date = new Date();
|
||||||
|
const context: any = {
|
||||||
|
fileName: path.basename(fsPath),
|
||||||
|
packageName: "",
|
||||||
|
typeName,
|
||||||
|
user: userInfo().username,
|
||||||
|
date: date.toLocaleDateString(undefined, {month: "short", day: "2-digit", year: "numeric"}),
|
||||||
|
time: date.toLocaleTimeString(),
|
||||||
|
year: date.getFullYear(),
|
||||||
|
month: formatNumber(date.getMonth() + 1),
|
||||||
|
shortmonth: date.toLocaleDateString(undefined, {month: "short"}),
|
||||||
|
day: formatNumber(date.getDate()),
|
||||||
|
hour: formatNumber(date.getHours()),
|
||||||
|
minute: formatNumber(date.getMinutes()),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isModuleInfo) {
|
||||||
|
context.packageName = packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileHeader = workspace.getConfiguration('java').get<string[]>("templates.fileHeader");
|
||||||
|
if (fileHeader && fileHeader.length) {
|
||||||
|
for (const template of fileHeader) {
|
||||||
|
snippets.push(stringInterpolate(template, context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isModuleInfo) {
|
||||||
|
if (context.packageName) {
|
||||||
|
snippets.push(`package ${context.packageName};`);
|
||||||
|
snippets.push("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isPackageInfo) {
|
||||||
|
const typeComment = workspace.getConfiguration('java').get<string[]>("templates.typeComment");
|
||||||
|
if (typeComment && typeComment.length) {
|
||||||
|
for (const template of typeComment) {
|
||||||
|
snippets.push(stringInterpolate(template, context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isModuleInfo) {
|
||||||
|
snippets.push(`module {`);
|
||||||
|
} else {
|
||||||
|
snippets.push(`public ${javaType.keyword} ${typeName}${javaType === JavaType.RECORD ? "()" : ""} {`);
|
||||||
|
}
|
||||||
|
snippets.push("");
|
||||||
|
snippets.push("}");
|
||||||
|
snippets.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
const workspaceEdit: WorkspaceEdit = new WorkspaceEdit();
|
||||||
|
const fsUri: Uri = Uri.file(fsPath);
|
||||||
|
workspaceEdit.createFile(fsUri);
|
||||||
|
workspaceEdit.insert(fsUri, new Position(0, 0), snippets.join("\n"));
|
||||||
|
await workspace.applyEdit(workspaceEdit);
|
||||||
|
const editor = await window.showTextDocument(fsUri);
|
||||||
|
if (editor) {
|
||||||
|
editor.document.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveTypeName(filePath: string): string {
|
||||||
|
const fileName: string = path.basename(filePath);
|
||||||
|
const extName: string = path.extname(fileName);
|
||||||
|
return fileName.substring(0, fileName.length - extName.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function newUntitledJavaFile(): Promise<void> {
|
async function newUntitledJavaFile(): Promise<void> {
|
||||||
|
@ -186,6 +353,62 @@ function canCreateClass(node: DataNode): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const COMPLIANCE = "org.eclipse.jdt.core.compiler.compliance";
|
||||||
|
async function isVersionLessThan(fileUri: string, targetVersion: number): Promise<boolean> {
|
||||||
|
let projectSettings: any = {};
|
||||||
|
try {
|
||||||
|
projectSettings = await commands.executeCommand<any>(
|
||||||
|
Commands.EXECUTE_WORKSPACE_COMMAND, Commands.GET_PROJECT_SETTINGS, fileUri, [ COMPLIANCE ]);
|
||||||
|
} catch (err) {
|
||||||
|
// do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
let javaVersion = 0;
|
||||||
|
let complianceVersion = projectSettings[COMPLIANCE];
|
||||||
|
if (complianceVersion) {
|
||||||
|
// Ignore '1.' prefix for legacy Java versions
|
||||||
|
if (complianceVersion.startsWith('1.')) {
|
||||||
|
complianceVersion = complianceVersion.substring(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// look into the interesting bits now
|
||||||
|
const regexp = /\d+/g;
|
||||||
|
const match = regexp.exec(complianceVersion);
|
||||||
|
if (match) {
|
||||||
|
javaVersion = parseInt(match[0], 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return javaVersion < targetVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resolvePackageName(filePath: string): Promise<string> {
|
||||||
|
let sourcePaths: string[] = [];
|
||||||
|
const result: IListCommandResult =
|
||||||
|
await commands.executeCommand<IListCommandResult>(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.LIST_SOURCEPATHS);
|
||||||
|
if (result && result.data && result.data.length) {
|
||||||
|
sourcePaths = result.data.map((sourcePath) => sourcePath.path).sort((a, b) => b.length - a.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sourcePaths || !sourcePaths.length) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const sourcePath of sourcePaths) {
|
||||||
|
if (isPrefix(sourcePath, filePath)) {
|
||||||
|
const relative = path.relative(sourcePath, path.dirname(filePath));
|
||||||
|
return relative.replace(/[/\\]/g, ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPrefix(parentPath: string, filePath: string): boolean {
|
||||||
|
const relative = path.relative(parentPath, filePath);
|
||||||
|
return !relative || (!relative.startsWith('..') && !path.isAbsolute(relative));
|
||||||
|
}
|
||||||
|
|
||||||
async function getPackageFsPath(node: DataNode): Promise<string | undefined> {
|
async function getPackageFsPath(node: DataNode): Promise<string | undefined> {
|
||||||
if (node.nodeData.kind === NodeKind.Project) {
|
if (node.nodeData.kind === NodeKind.Project) {
|
||||||
const childrenNodes: DataNode[] = await node.getChildren() as DataNode[];
|
const childrenNodes: DataNode[] = await node.getChildren() as DataNode[];
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { DependencyExplorer } from "./views/dependencyExplorer";
|
||||||
import { DiagnosticProvider } from "./tasks/buildArtifact/migration/DiagnosticProvider";
|
import { DiagnosticProvider } from "./tasks/buildArtifact/migration/DiagnosticProvider";
|
||||||
import { setContextForDeprecatedTasks, updateExportTaskType } from "./tasks/buildArtifact/migration/utils";
|
import { setContextForDeprecatedTasks, updateExportTaskType } from "./tasks/buildArtifact/migration/utils";
|
||||||
import { CodeActionProvider } from "./tasks/buildArtifact/migration/CodeActionProvider";
|
import { CodeActionProvider } from "./tasks/buildArtifact/migration/CodeActionProvider";
|
||||||
import { newJavaClass } from "./explorerCommands/new";
|
import { newJavaFile } from "./explorerCommands/new";
|
||||||
|
|
||||||
export async function activate(context: ExtensionContext): Promise<void> {
|
export async function activate(context: ExtensionContext): Promise<void> {
|
||||||
contextManager.initialize(context);
|
contextManager.initialize(context);
|
||||||
|
@ -47,7 +47,7 @@ async function activateExtension(_operationId: string, context: ExtensionContext
|
||||||
context.subscriptions.push(tasks.registerTaskProvider(DeprecatedExportJarTaskProvider.type, new DeprecatedExportJarTaskProvider()));
|
context.subscriptions.push(tasks.registerTaskProvider(DeprecatedExportJarTaskProvider.type, new DeprecatedExportJarTaskProvider()));
|
||||||
context.subscriptions.push(tasks.registerTaskProvider(BuildArtifactTaskProvider.exportJarType, new BuildArtifactTaskProvider()));
|
context.subscriptions.push(tasks.registerTaskProvider(BuildArtifactTaskProvider.exportJarType, new BuildArtifactTaskProvider()));
|
||||||
context.subscriptions.push(tasks.registerTaskProvider(BuildTaskProvider.type, new BuildTaskProvider()));
|
context.subscriptions.push(tasks.registerTaskProvider(BuildTaskProvider.type, new BuildTaskProvider()));
|
||||||
context.subscriptions.push(instrumentOperationAsVsCodeCommand(Commands.VIEW_MENUS_FILE_NEW_JAVA_CLASS, newJavaClass));
|
context.subscriptions.push(instrumentOperationAsVsCodeCommand(Commands.VIEW_MENUS_FILE_NEW_JAVA_CLASS, newJavaFile));
|
||||||
context.subscriptions.push(window.onDidChangeActiveTextEditor((e: TextEditor | undefined) => {
|
context.subscriptions.push(window.onDidChangeActiveTextEditor((e: TextEditor | undefined) => {
|
||||||
setContextForReloadProject(e?.document);
|
setContextForReloadProject(e?.document);
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -121,6 +121,11 @@ export class PrimaryTypeNode extends DataNode {
|
||||||
contextValue += "+test";
|
contextValue += "+test";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._rootNode?.getParent() instanceof ProjectNode
|
||||||
|
&& (this._rootNode.getParent() as ProjectNode).nodeData?.metaData?.MaxSourceVersion >= 16) {
|
||||||
|
contextValue += "+allowRecord";
|
||||||
|
}
|
||||||
|
|
||||||
return contextValue;
|
return contextValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
import { instrumentOperationAsVsCodeCommand, sendInfo } from "vscode-extension-telemetry-wrapper";
|
import { instrumentOperationAsVsCodeCommand, sendInfo } from "vscode-extension-telemetry-wrapper";
|
||||||
import { Commands } from "../commands";
|
import { Commands } from "../commands";
|
||||||
import { deleteFiles } from "../explorerCommands/delete";
|
import { deleteFiles } from "../explorerCommands/delete";
|
||||||
import { newFile, newFolder, newJavaClass, newPackage, newResource } from "../explorerCommands/new";
|
import { JavaType, newFile, newFolder, newJavaFileWithSpecificType, newPackage, newResource } from "../explorerCommands/new";
|
||||||
import { renameFile } from "../explorerCommands/rename";
|
import { renameFile } from "../explorerCommands/rename";
|
||||||
import { getCmdNode } from "../explorerCommands/utility";
|
import { getCmdNode } from "../explorerCommands/utility";
|
||||||
import { Jdtls } from "../java/jdtls";
|
import { Jdtls } from "../java/jdtls";
|
||||||
|
@ -117,7 +117,22 @@ export class DependencyExplorer implements Disposable {
|
||||||
newResource(node);
|
newResource(node);
|
||||||
}),
|
}),
|
||||||
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_JAVA_CLASS, async (node?: DataNode) => {
|
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_JAVA_CLASS, async (node?: DataNode) => {
|
||||||
newJavaClass(node);
|
newJavaFileWithSpecificType(JavaType.CLASS, node);
|
||||||
|
}),
|
||||||
|
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_JAVA_INTERFACE, async (node?: DataNode) => {
|
||||||
|
newJavaFileWithSpecificType(JavaType.INTERFACE, node);
|
||||||
|
}),
|
||||||
|
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_JAVA_ENUM, async (node?: DataNode) => {
|
||||||
|
newJavaFileWithSpecificType(JavaType.ENUM, node);
|
||||||
|
}),
|
||||||
|
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_JAVA_RECORD, async (node?: DataNode) => {
|
||||||
|
newJavaFileWithSpecificType(JavaType.RECORD, node);
|
||||||
|
}),
|
||||||
|
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_JAVA_ANNOTATION, async (node?: DataNode) => {
|
||||||
|
newJavaFileWithSpecificType(JavaType.ANNOTATION, node);
|
||||||
|
}),
|
||||||
|
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_JAVA_ABSTRACT_CLASS, async (node?: DataNode) => {
|
||||||
|
newJavaFileWithSpecificType(JavaType.ABSTRACT_CLASS, node);
|
||||||
}),
|
}),
|
||||||
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_FILE, async (node: DataNode) => {
|
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_FILE, async (node: DataNode) => {
|
||||||
newFile(node);
|
newFile(node);
|
||||||
|
|
|
@ -50,6 +50,9 @@ export class PackageNode extends DataNode {
|
||||||
let contextValue: string = Explorer.ContextValueType.Package;
|
let contextValue: string = Explorer.ContextValueType.Package;
|
||||||
if (parentData.entryKind === PackageRootKind.K_SOURCE || parentData.kind === NodeKind.Project) {
|
if (parentData.entryKind === PackageRootKind.K_SOURCE || parentData.kind === NodeKind.Project) {
|
||||||
contextValue += "+source";
|
contextValue += "+source";
|
||||||
|
if (this._project.nodeData.metaData?.MaxSourceVersion >= 16) {
|
||||||
|
contextValue += "+allowRecord";
|
||||||
|
}
|
||||||
} else if (parentData.entryKind === PackageRootKind.K_BINARY) {
|
} else if (parentData.entryKind === PackageRootKind.K_BINARY) {
|
||||||
contextValue += "+binary";
|
contextValue += "+binary";
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,9 @@ export class PackageRootNode extends DataNode {
|
||||||
} else {
|
} else {
|
||||||
contextValue += "+source";
|
contextValue += "+source";
|
||||||
}
|
}
|
||||||
|
if (this._project.nodeData.metaData?.MaxSourceVersion >= 16) {
|
||||||
|
contextValue += "+allowRecord";
|
||||||
|
}
|
||||||
return contextValue;
|
return contextValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,9 @@ export class ProjectNode extends DataNode {
|
||||||
const attributeString: string = getProjectTypeAttributes(natureIds);
|
const attributeString: string = getProjectTypeAttributes(natureIds);
|
||||||
contextValue += attributeString;
|
contextValue += attributeString;
|
||||||
}
|
}
|
||||||
|
if (this.nodeData.metaData?.MaxSourceVersion >= 16) {
|
||||||
|
contextValue += "+allowRecord";
|
||||||
|
}
|
||||||
return contextValue;
|
return contextValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,14 +114,14 @@ describe("Command Tests", function() {
|
||||||
|
|
||||||
it("Test java.view.package.newJavaClass", async function() {
|
it("Test java.view.package.newJavaClass", async function() {
|
||||||
let inputBox = await createJavaResource();
|
let inputBox = await createJavaResource();
|
||||||
const javaClassQuickPick = await inputBox.findQuickPick("Java Class");
|
const javaClassQuickPick = await inputBox.findQuickPick(0);
|
||||||
await javaClassQuickPick!.click();
|
await javaClassQuickPick!.click();
|
||||||
assert.ok(await inputBox.getPlaceHolder() === "Choose a source folder", `InputBox "Choose a source folder" should appear`);
|
assert.ok(await inputBox.getPlaceHolder() === "Choose a source folder", `InputBox "Choose a source folder" should appear`);
|
||||||
const quickPick = await inputBox.findQuickPick("src/main/java");
|
const quickPick = await inputBox.findQuickPick("src/main/java");
|
||||||
assert.ok(quickPick, `Quickpick item "src/main/java" should be found`);
|
assert.ok(quickPick, `Quickpick item "src/main/java" should be found`);
|
||||||
await quickPick!.click();
|
await quickPick!.click();
|
||||||
inputBox = await InputBox.create();
|
inputBox = await InputBox.create();
|
||||||
assert.ok(await inputBox.getPlaceHolder() === "Enter the Java file name for class/interface/enum/record/@interface", `InputBox "Enter the Java file name" should appear`);
|
assert.ok(await inputBox.getPlaceHolder() === "Input the class name", `InputBox "Input the class name" should appear`);
|
||||||
await inputBox.setText("App2");
|
await inputBox.setText("App2");
|
||||||
await inputBox.confirm();
|
await inputBox.confirm();
|
||||||
await sleep(1000);
|
await sleep(1000);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче