Skip to content

Commit 574e6c3

Browse files
author
Rob Stryker
committed
WIP - alternate solution to CompletionContextTests.test0123
Signed-off-by: Rob Stryker <stryker@redhat.com>
1 parent 2291e4a commit 574e6c3

File tree

5 files changed

+84
-24
lines changed

5 files changed

+84
-24
lines changed

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacCompilationUnitResolver.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ private void resolveRequestedBindingKeys(JavacBindingResolver bindingResolver, S
283283
var compiler = ToolProvider.getSystemJavaCompiler();
284284
var context = new Context();
285285
JavacTask task = (JavacTask) compiler.getTask(null, null, null, List.of(), List.of(), List.of());
286-
bindingResolver = new JavacBindingResolver(null, task, context, new JavacConverter(null, null, context, null, true, -1), null, null);
286+
bindingResolver = new JavacBindingResolver(null, task, context, createJavacConverter(opts.getMap(), null, null, context, null, true, -1), null, null);
287287
}
288288

289289
for (CompilationUnit cu : units) {
@@ -744,7 +744,7 @@ public Void visitClass(ClassTree node, Void p) {
744744
}
745745
CompilationUnit res = result.get(sourceUnits[i]);
746746
AST ast = res.ast;
747-
JavacConverter converter = new JavacConverter(ast, javacCompilationUnit, context, rawText, docEnabled, focalPoint);
747+
JavacConverter converter = createJavacConverter(compilerOptions, ast, javacCompilationUnit, context, rawText, docEnabled, focalPoint);
748748
converter.populateCompilationUnit(res, javacCompilationUnit);
749749
// javadoc problems explicitly set as they're not sent to DiagnosticListener (maybe find a flag to do it?)
750750
var javadocProblems = converter.javadocDiagnostics.stream()
@@ -849,7 +849,17 @@ public void postVisit(ASTNode node) {
849849

850850
return result;
851851
}
852-
852+
853+
private JavacConverter createJavacConverter(Map<String, String> compilerOptions, AST ast, JCCompilationUnit javacCompilationUnit,
854+
Context context, String rawText, boolean docEnabled, int focalPoint) {
855+
String v = compilerOptions.get(org.eclipse.jdt.internal.core.CompilationUnit.COMPILER_COMPLETION_PARSER_ATTR);
856+
if( "true".equals(v)) {
857+
return new JavacCompletionConverter(ast, javacCompilationUnit, context, rawText, docEnabled, focalPoint);
858+
} else {
859+
return new JavacConverter(ast, javacCompilationUnit, context, rawText, docEnabled, focalPoint);
860+
}
861+
}
862+
853863
/// cleans up context after analysis (nothing left to process)
854864
/// but remain it usable by bindings by keeping filemanager available.
855865
public static void cleanup(Context context) {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024, Red Hat, Inc. and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
package org.eclipse.jdt.core.dom;
12+
13+
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
14+
import com.sun.tools.javac.tree.JCTree.JCErroneous;
15+
import com.sun.tools.javac.util.Context;
16+
17+
public class JavacCompletionConverter extends JavacConverter {
18+
19+
public JavacCompletionConverter(AST ast, JCCompilationUnit javacCompilationUnit, Context context, String rawText,
20+
boolean buildJavadoc, int focalPoint) {
21+
super(ast, javacCompilationUnit, context, rawText, buildJavadoc, focalPoint);
22+
}
23+
protected Expression convertErroneousExpression(JCErroneous error) {
24+
Expression e = super.convertErroneousExpression(error);
25+
if( e == null ) {
26+
int pos = error.getPreferredPosition();
27+
char c = this.rawText.length() > pos ? this.rawText.charAt(pos) : 0;
28+
if (error.getErrorTrees().isEmpty() && c == '"') {
29+
int newLine = this.rawText.indexOf('\n', pos);
30+
int lineEnd = newLine == -1 ? this.rawText.length() - 1 : newLine;
31+
String litText = this.rawText.substring(pos+1, lineEnd);
32+
Expression res = convertStringToLiteral(litText, pos, lineEnd, null);
33+
res.setSourceRange(pos, lineEnd - pos);
34+
return res;
35+
}
36+
}
37+
return e;
38+
}
39+
}

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacConverter.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ private JavacConverter(AST ast, JCCompilationUnit javacCompilationUnit, Context
161161
this.buildJavadoc = buildJavadoc;
162162
this.focalPoint = -1;
163163
}
164+
164165
public JavacConverter(AST ast, JCCompilationUnit javacCompilationUnit,
165166
Context context, String rawText, boolean buildJavadoc, int focalPoint) {
166167
this(ast, javacCompilationUnit, context, rawText, buildJavadoc);
@@ -2009,25 +2010,9 @@ private Expression convertExpression(JCExpression javac) {
20092010

20102011
// Handle errors or default situation
20112012
if (javac instanceof JCErroneous error) {
2012-
int pos = javac.getPreferredPosition();
2013-
char c = this.rawText.length() > pos ? this.rawText.charAt(pos) : 0;
2014-
if (error.getErrorTrees().isEmpty() && c == '"') {
2015-
int newLine = this.rawText.indexOf('\n', pos);
2016-
int lineEnd = newLine == -1 ? this.rawText.length() - 1 : newLine;
2017-
String litText = this.rawText.substring(pos+1, lineEnd);
2018-
Expression res = convertStringToLiteral(litText, pos, lineEnd, null);
2019-
res.setSourceRange(pos, lineEnd - pos);
2020-
return res;
2021-
}
2022-
if (error.getErrorTrees().size() == 1) {
2023-
JCTree tree = error.getErrorTrees().get(0);
2024-
if (tree instanceof JCExpression nestedExpr) {
2025-
try {
2026-
return convertExpression(nestedExpr);
2027-
} catch (Exception ex) {
2028-
// pass-through: do not break when attempting such reconcile
2029-
}
2030-
}
2013+
Expression e = convertErroneousExpression(error);
2014+
if( e != null ) {
2015+
return e;
20312016
}
20322017
}
20332018
if( shouldRecoverWithSimpleName(javac)) {
@@ -2038,6 +2023,20 @@ private Expression convertExpression(JCExpression javac) {
20382023
}
20392024
return null;
20402025
}
2026+
2027+
protected Expression convertErroneousExpression(JCErroneous error) {
2028+
if (error.getErrorTrees().size() == 1) {
2029+
JCTree tree = error.getErrorTrees().get(0);
2030+
if (tree instanceof JCExpression nestedExpr) {
2031+
try {
2032+
return convertExpression(nestedExpr);
2033+
} catch (Exception ex) {
2034+
// pass-through: do not break when attempting such reconcile
2035+
}
2036+
}
2037+
}
2038+
return null;
2039+
}
20412040

20422041
private boolean shouldRecoverWithSimpleName(JCExpression javac) {
20432042
if( javac instanceof JCNewClass)
@@ -2297,7 +2296,7 @@ private Expression convertLiteral(JCLiteral literal) {
22972296
throw new UnsupportedOperationException("Not supported yet " + literal + "\n of type" + literal.getClass().getName());
22982297
}
22992298

2300-
private Expression convertStringToLiteral(String string, int pos, int endPos, JCLiteral literal) {
2299+
protected Expression convertStringToLiteral(String string, int pos, int endPos, JCLiteral literal) {
23012300
boolean malformed = false;
23022301
if (this.rawText.charAt(pos) == '"'
23032302
&& this.rawText.charAt(pos + 1) == '"'

org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionContextTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3374,6 +3374,8 @@ public void test0122() throws JavaModelException {
33743374
"completion token location=UNKNOWN",
33753375
result.context);
33763376
}
3377+
3378+
// TODO The dom tree has an added node called CompletionOnStringLiteral that the regular tree doesn't have.
33773379
public void test0123() throws JavaModelException {
33783380
this.workingCopies = new ICompilationUnit[1];
33793381
this.workingCopies[0] = getWorkingCopy(

org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
public class CompilationUnit extends Openable implements ICompilationUnit, org.eclipse.jdt.internal.compiler.env.ICompilationUnit, SuffixConstants {
7272
public static boolean DOM_BASED_OPERATIONS = Boolean.getBoolean(CompilationUnit.class.getSimpleName() + ".DOM_BASED_OPERATIONS"); //$NON-NLS-1$
7373
public static boolean DOM_BASED_COMPLETION = Boolean.getBoolean(CompilationUnit.class.getSimpleName() + ".codeComplete.DOM_BASED_OPERATIONS"); //$NON-NLS-1$
74+
public static String COMPILER_COMPLETION_PARSER_ATTR = JavaCore.PLUGIN_ID + ".compiler.completion.parser.enablement"; //$NON-NLS-1$
7475

7576
/**
7677
* Internal synonym for deprecated constant AST.JSL2
@@ -458,7 +459,7 @@ public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyO
458459
@Override
459460
public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor) throws JavaModelException {
460461
if (DOM_BASED_COMPLETION) {
461-
new DOMCompletionEngine(offset, getOrBuildAST(workingCopyOwner, offset), this, workingCopyOwner, requestor, monitor).run();
462+
new DOMCompletionEngine(offset, getOrBuildCompletionAST(workingCopyOwner, offset), this, workingCopyOwner, requestor, monitor).run();
462463
return;
463464
}
464465
codeComplete(
@@ -490,11 +491,20 @@ public IJavaElement[] codeSelect(int offset, int length, WorkingCopyOwner workin
490491
}
491492
}
492493

494+
public org.eclipse.jdt.core.dom.CompilationUnit getOrBuildCompletionAST(WorkingCopyOwner workingCopyOwner, int focalPosition) throws JavaModelException {
495+
return getOrBuildAST(workingCopyOwner, focalPosition, Map.of(COMPILER_COMPLETION_PARSER_ATTR, Boolean.TRUE.toString()));
496+
}
497+
493498
public org.eclipse.jdt.core.dom.CompilationUnit getOrBuildAST(WorkingCopyOwner workingCopyOwner, int focalPosition) throws JavaModelException {
499+
return getOrBuildAST(workingCopyOwner, focalPosition, Collections.EMPTY_MAP);
500+
}
501+
502+
private org.eclipse.jdt.core.dom.CompilationUnit getOrBuildAST(WorkingCopyOwner workingCopyOwner, int focalPosition, Map<String,String> additionalCompilerOptions) throws JavaModelException {
494503
if (this.ast != null) {
495504
return this.ast;
496505
}
497506
Map<String, String> options = getOptions(true);
507+
options.putAll(additionalCompilerOptions);
498508
ASTParser parser = ASTParser.newParser(new AST(options).apiLevel()); // go through AST constructor to convert options to apiLevel
499509
// but we should probably instead just use the latest Java version
500510
// supported by the compiler

0 commit comments

Comments
 (0)