Skip to content

Commit a0dcf41

Browse files
feat: Improve the user experience of new Java file. (#801)
1 parent 69268d9 commit a0dcf41

File tree

16 files changed

+455
-53
lines changed

16 files changed

+455
-53
lines changed

ThirdPartyNotices.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ This project incorporates components from the projects listed below. The origina
1313
6. jprichardson/node-fs-extra (https://github.com/jprichardson/node-fs-extra)
1414
7. lodash/lodash (https://github.com/lodash/lodash)
1515
8. sindresorhus/globby (https://github.com/sindresorhus/globby)
16+
9. tcort/fmtr (https://github.com/tcort/fmtr)
1617

1718
%% Apache Commons Lang NOTICES AND INFORMATION BEGIN HERE
1819
=========================================
@@ -571,3 +572,15 @@ The above copyright notice and this permission notice shall be included in all c
571572
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.
572573
=========================================
573574
END OF sindresorhus/globby NOTICES AND INFORMATION
575+
576+
%% tcort/fmtr NOTICES AND INFORMATION BEGIN HERE
577+
=========================================
578+
ISC License
579+
580+
Copyright (c) 2015-2021 Thomas Cort linuxgeek@gmail.com
581+
582+
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.
583+
584+
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.
585+
=========================================
586+
END OF tcort/fmtr NOTICES AND INFORMATION

jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/model/PackageNode.java

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.eclipse.jdt.core.IType;
3737
import org.eclipse.jdt.core.JavaCore;
3838
import org.eclipse.jdt.core.JavaModelException;
39+
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
40+
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
3941
import org.eclipse.jdt.internal.core.JrtPackageFragmentRoot;
4042
import org.eclipse.jdt.ls.core.internal.JDTUtils;
4143
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
@@ -68,9 +70,11 @@ public class PackageNode {
6870
public static final String REFERENCED_LIBRARIES_PATH = "REFERENCED_LIBRARIES_PATH";
6971
private static final String REFERENCED_LIBRARIES_CONTAINER_NAME = "Referenced Libraries";
7072
private static final String IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER_NAME = "Referenced Libraries (Read-only)";
71-
public static final ContainerNode REFERENCED_LIBRARIES_CONTAINER = new ContainerNode(REFERENCED_LIBRARIES_CONTAINER_NAME, REFERENCED_LIBRARIES_PATH,
73+
public static final ContainerNode REFERENCED_LIBRARIES_CONTAINER = new ContainerNode(
74+
REFERENCED_LIBRARIES_CONTAINER_NAME, REFERENCED_LIBRARIES_PATH,
7275
NodeKind.CONTAINER, IClasspathEntry.CPE_CONTAINER);
73-
public static final ContainerNode IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER = new ContainerNode(IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER_NAME,
76+
public static final ContainerNode IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER = new ContainerNode(
77+
IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER_NAME,
7478
REFERENCED_LIBRARIES_PATH, NodeKind.CONTAINER, IClasspathEntry.CPE_CONTAINER);
7579

7680
/**
@@ -85,6 +89,8 @@ public class PackageNode {
8589
*/
8690
private static final String UNMANAGED_FOLDER_NATURE_ID = "org.eclipse.jdt.ls.core.unmanagedFolder";
8791

92+
private static final String MAX_SOURCE_VERSION = "MaxSourceVersion";
93+
8894
/**
8995
* The name of the PackageNode.
9096
*/
@@ -164,7 +170,8 @@ public static PackageNode createNodeForProject(IJavaElement javaElement) {
164170
return null;
165171
}
166172
IProject proj = javaElement.getJavaProject().getProject();
167-
PackageNode projectNode = new PackageNode(proj.getName(), proj.getFullPath().toPortableString(), NodeKind.PROJECT);
173+
PackageNode projectNode = new PackageNode(proj.getName(), proj.getFullPath().toPortableString(),
174+
NodeKind.PROJECT);
168175
projectNode.setUri(ProjectUtils.getProjectRealFolder(proj).toFile().toURI().toString());
169176
try {
170177
List<String> natureIds = new ArrayList<>(Arrays.asList(proj.getDescription().getNatureIds()));
@@ -173,6 +180,10 @@ public static PackageNode createNodeForProject(IJavaElement javaElement) {
173180
projectNode.setMetaDataValue(UNMANAGED_FOLDER_INNER_PATH, proj.getLocationURI().toString());
174181
}
175182
projectNode.setMetaDataValue(NATURE_ID, natureIds);
183+
String sourceVersion = javaElement.getJavaProject().getOption(JavaCore.COMPILER_SOURCE, true);
184+
int jdkLevel = (int) (CompilerOptions.versionToJdkLevel(sourceVersion, true) >>> 16);
185+
int majorVersion = Math.max(0, jdkLevel - ClassFileConstants.MAJOR_VERSION_0);
186+
projectNode.setMetaDataValue(MAX_SOURCE_VERSION, majorVersion);
176187
} catch (CoreException e) {
177188
// do nothing
178189
}
@@ -201,7 +212,8 @@ public static PackageNode createNodeForResource(IResource resource) {
201212
}
202213

203214
public static PackageNode createNodeForPackageFragment(IPackageFragment packageFragment) {
204-
PackageNode fragmentNode = new PackageNode(packageFragment.getElementName(), packageFragment.getPath().toPortableString(), NodeKind.PACKAGE);
215+
PackageNode fragmentNode = new PackageNode(packageFragment.getElementName(),
216+
packageFragment.getPath().toPortableString(), NodeKind.PACKAGE);
205217
fragmentNode.setHandlerIdentifier(packageFragment.getHandleIdentifier());
206218
if (packageFragment.getResource() != null) {
207219
fragmentNode.setUri(packageFragment.getResource().getLocationURI().toString());
@@ -215,16 +227,19 @@ public static PackageNode createNodeForVirtualContainer(IPackageFragmentRoot pkg
215227
IClasspathEntry entry = pkgRoot.getRawClasspathEntry();
216228
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), pkgRoot.getJavaProject());
217229
PackageNode containerNode = null;
218-
if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
230+
if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY
231+
|| entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
219232
containerNode = REFERENCED_LIBRARIES_CONTAINER;
220233
} else {
221-
containerNode = new ContainerNode(container.getDescription(), container.getPath().toPortableString(), NodeKind.CONTAINER, entry.getEntryKind());
234+
containerNode = new ContainerNode(container.getDescription(), container.getPath().toPortableString(),
235+
NodeKind.CONTAINER, entry.getEntryKind());
222236
}
223237
return containerNode;
224238

225239
}
226240

227-
public static PackageRootNode createNodeForPackageFragmentRoot(IPackageFragmentRoot pkgRoot) throws JavaModelException {
241+
public static PackageRootNode createNodeForPackageFragmentRoot(IPackageFragmentRoot pkgRoot)
242+
throws JavaModelException {
228243
PackageRootNode node;
229244
String displayName = pkgRoot.getElementName();
230245
boolean isSourcePath = pkgRoot.getKind() == IPackageFragmentRoot.K_SOURCE;
@@ -271,14 +286,16 @@ public static PackageRootNode createNodeForPackageFragmentRoot(IPackageFragmentR
271286
* Get the correspond node of classpath, it may be container or a package root.
272287
*
273288
* @param classpathEntry
274-
* classpath entry
289+
* classpath entry
275290
* @param javaProject
276-
* correspond java project
291+
* correspond java project
277292
* @param nodeKind
278-
* could be CONTAINER or PACKAGEROOT(for referenced libraries)
293+
* could be CONTAINER or PACKAGEROOT(for referenced
294+
* libraries)
279295
* @return correspond PackageNode of classpath entry
280296
*/
281-
public static PackageNode createNodeForClasspathEntry(IClasspathEntry classpathEntry, IJavaProject javaProject, NodeKind nodeKind) {
297+
public static PackageNode createNodeForClasspathEntry(IClasspathEntry classpathEntry, IJavaProject javaProject,
298+
NodeKind nodeKind) {
282299
try {
283300
IClasspathEntry entry = JavaCore.getResolvedClasspathEntry(classpathEntry);
284301
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
@@ -289,17 +306,18 @@ public static PackageNode createNodeForClasspathEntry(IClasspathEntry classpathE
289306
if (container != null) {
290307
PackageNode node = null;
291308
if (nodeKind == NodeKind.CONTAINER) {
292-
node = new ContainerNode(container.getDescription(), container.getPath().toPortableString(), nodeKind, entry.getEntryKind());
309+
node = new ContainerNode(container.getDescription(), container.getPath().toPortableString(),
310+
nodeKind, entry.getEntryKind());
293311
final URI containerURI = ExtUtils.getContainerURI(javaProject, container);
294312
node.setUri(containerURI != null ? containerURI.toString() : null);
295313
} else if (nodeKind == NodeKind.PACKAGEROOT) { // ClasspathEntry for referenced jar files
296314
// Use package name as package root name
297315
String[] pathSegments = container.getPath().segments();
298316
node = new PackageRootNode(
299-
pathSegments[pathSegments.length - 1],
300-
container.getPath().toPortableString(),
301-
container.getPath().toFile().toURI().toString(),
302-
nodeKind, IPackageFragmentRoot.K_BINARY);
317+
pathSegments[pathSegments.length - 1],
318+
container.getPath().toPortableString(),
319+
container.getPath().toFile().toURI().toString(),
320+
nodeKind, IPackageFragmentRoot.K_BINARY);
303321
}
304322
return node;
305323
}
@@ -310,7 +328,8 @@ public static PackageNode createNodeForClasspathEntry(IClasspathEntry classpathE
310328
}
311329

312330
public static PackageNode createNodeForPrimaryType(IType type) {
313-
PackageNode primaryTypeNode = new PackageNode(type.getElementName(), type.getPath().toPortableString(), NodeKind.PRIMARYTYPE);
331+
PackageNode primaryTypeNode = new PackageNode(type.getElementName(), type.getPath().toPortableString(),
332+
NodeKind.PRIMARYTYPE);
314333

315334
try {
316335
if (type.isEnum()) {
@@ -332,7 +351,7 @@ public static PackageNode createNodeForPrimaryType(IType type) {
332351
* Get correspond node of referenced variable.
333352
*
334353
* @param classpathEntry
335-
* referenced variable's classpath entry
354+
* referenced variable's classpath entry
336355
* @return correspond package node
337356
*/
338357
public static PackageRootNode createNodeForClasspathVariable(IClasspathEntry classpathEntry) {

package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,36 @@
192192
"category": "Java",
193193
"icon": "$(add)"
194194
},
195+
{
196+
"command": "java.view.package.newJavaInterface",
197+
"title": "%contributes.commands.java.view.package.newJavaInterface%",
198+
"category": "Java",
199+
"icon": "$(add)"
200+
},
201+
{
202+
"command": "java.view.package.newJavaEnum",
203+
"title": "%contributes.commands.java.view.package.newJavaEnum%",
204+
"category": "Java",
205+
"icon": "$(add)"
206+
},
207+
{
208+
"command": "java.view.package.newJavaRecord",
209+
"title": "%contributes.commands.java.view.package.newJavaRecord%",
210+
"category": "Java",
211+
"icon": "$(add)"
212+
},
213+
{
214+
"command": "java.view.package.newJavaAnnotation",
215+
"title": "%contributes.commands.java.view.package.newJavaAnnotation%",
216+
"category": "Java",
217+
"icon": "$(add)"
218+
},
219+
{
220+
"command": "java.view.package.newJavaAbstractClass",
221+
"title": "%contributes.commands.java.view.package.newJavaAbstractClass%",
222+
"category": "Java",
223+
"icon": "$(add)"
224+
},
195225
{
196226
"command": "java.view.package.newPackage",
197227
"title": "%contributes.commands.java.view.package.newPackage%",
@@ -395,6 +425,26 @@
395425
"command": "java.view.package.newJavaClass",
396426
"when": "false"
397427
},
428+
{
429+
"command": "java.view.package.newJavaInterface",
430+
"when": "false"
431+
},
432+
{
433+
"command": "java.view.package.newJavaEnum",
434+
"when": "false"
435+
},
436+
{
437+
"command": "java.view.package.newJavaRecord",
438+
"when": "false"
439+
},
440+
{
441+
"command": "java.view.package.newJavaAnnotation",
442+
"when": "false"
443+
},
444+
{
445+
"command": "java.view.package.newJavaAbstractClass",
446+
"when": "false"
447+
},
398448
{
399449
"command": "java.view.package.newPackage",
400450
"when": "false"
@@ -641,21 +691,46 @@
641691
"javaProject.new": [
642692
{
643693
"command": "java.view.package.newJavaClass",
644-
"group": "new@10",
694+
"group": "new1@10",
695+
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
696+
},
697+
{
698+
"command": "java.view.package.newJavaInterface",
699+
"group": "new1@11",
700+
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
701+
},
702+
{
703+
"command": "java.view.package.newJavaEnum",
704+
"group": "new1@12",
705+
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
706+
},
707+
{
708+
"command": "java.view.package.newJavaRecord",
709+
"group": "new1@13",
710+
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/) && viewItem =~ /java:.*\\+allowRecord\\b/"
711+
},
712+
{
713+
"command": "java.view.package.newJavaAnnotation",
714+
"group": "new1@14",
715+
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
716+
},
717+
{
718+
"command": "java.view.package.newJavaAbstractClass",
719+
"group": "new1@15",
645720
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
646721
},
647722
{
648723
"command": "java.view.package.newPackage",
649-
"group": "new@20",
724+
"group": "new1@20",
650725
"when": "view == javaProjectExplorer && (viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)/ || viewItem =~ /java:project(?=.*?\\b\\+java\\b)/ || viewItem =~ /java:type/)"
651726
},
652727
{
653728
"command": "java.view.package.newFile",
654-
"group": "new@30"
729+
"group": "new2@30"
655730
},
656731
{
657732
"command": "java.view.package.newFolder",
658-
"group": "new@40",
733+
"group": "new2@40",
659734
"when": "view == javaProjectExplorer && (viewItem =~ /java:(file|folder|project)/ || viewItem =~ /java:(packageRoot)(?=.*?\\b\\+resource\\b)/)"
660735
}
661736
]
@@ -895,6 +970,7 @@
895970
},
896971
"dependencies": {
897972
"await-lock": "^2.2.2",
973+
"fmtr": "^1.1.4",
898974
"fs-extra": "^10.1.0",
899975
"globby": "^13.1.3",
900976
"lodash": "^4.17.21",

package.nls.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@
2222
"contributes.commands.java.view.package.copyFilePath": "Copy Path",
2323
"contributes.commands.java.view.package.copyRelativeFilePath": "Copy Relative Path",
2424
"contributes.commands.java.view.package.new": "New...",
25-
"contributes.commands.java.view.package.newJavaClass": "Java Class...",
25+
"contributes.commands.java.view.package.newJavaClass": "Class...",
26+
"contributes.commands.java.view.package.newJavaInterface": "Interface...",
27+
"contributes.commands.java.view.package.newJavaEnum": "Enum...",
28+
"contributes.commands.java.view.package.newJavaRecord": "Record...",
29+
"contributes.commands.java.view.package.newJavaAnnotation": "Annotation...",
30+
"contributes.commands.java.view.package.newJavaAbstractClass": "Abstract Class...",
2631
"contributes.commands.java.view.package.newPackage": "Package...",
2732
"contributes.commands.java.view.package.newFile": "File...",
28-
"contributes.commands.java.view.package.newFolder": "Folder",
33+
"contributes.commands.java.view.package.newFolder": "Folder...",
2934
"contributes.commands.java.view.package.renameFile": "Rename",
3035
"contributes.commands.java.view.package.moveFileToTrash": "Delete",
3136
"contributes.commands.java.view.package.deleteFilePermanently": "Delete Permanently",

package.nls.zh-cn.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@
2222
"contributes.commands.java.view.package.copyFilePath": "复制路径",
2323
"contributes.commands.java.view.package.copyRelativeFilePath": "复制相对路径",
2424
"contributes.commands.java.view.package.new": "创建...",
25-
"contributes.commands.java.view.package.newJavaClass": "Java 类...",
25+
"contributes.commands.java.view.package.newJavaClass": "类...",
26+
"contributes.commands.java.view.package.newJavaInterface": "接口类型...",
27+
"contributes.commands.java.view.package.newJavaEnum": "枚举类型...",
28+
"contributes.commands.java.view.package.newJavaRecord": "记录类型...",
29+
"contributes.commands.java.view.package.newJavaAnnotation": "注解类型...",
30+
"contributes.commands.java.view.package.newJavaAbstractClass": "抽象类型...",
2631
"contributes.commands.java.view.package.newPackage": "包...",
2732
"contributes.commands.java.view.package.newFile": "文件...",
28-
"contributes.commands.java.view.package.newFolder": "文件夹",
33+
"contributes.commands.java.view.package.newFolder": "文件夹...",
2934
"contributes.commands.java.view.package.renameFile": "重命名",
3035
"contributes.commands.java.view.package.moveFileToTrash": "删除",
3136
"contributes.commands.java.view.package.deleteFilePermanently": "永久删除",

0 commit comments

Comments
 (0)