-
Notifications
You must be signed in to change notification settings - Fork 408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Code actions should return textedits with proper formatting #1157
Comments
@jdneo Given you have a look at the formatting issue before, could you take over this area? |
@testforstephen Sure. Let me take a look. |
Since the formatting issue has to be fixed case by case, below is a list of the code actions we support now, some effort is needed to check if any of them need to migrate to the new implementation.
|
At the moment, the JDT code actions are all using ASTRewrite.rewriteAST() to generate the text edit, where it reads the formatting options from both the project and JavaCore.getOptions() by default. See In order to make code actions to return textedits with the correct formatting, it is critical to pass the correct formatting to ASTRewrite. If the client only supports configuring formatting options at the workspace level, we just need to reuse JavaCore.setOptions() to convert the client's formatting options to JDT preferences and ASTRewrite will automatically get the correct formatting. However, if the client is allowed to configure indentation for each Java file (as VS Code does), it may not be appropriate to continue to reuse JavaCore to pass on formatting preferences, as this would cause JavaCore to change each time a new Java file is opened. The alternative is to explicitly pass the formatting settings for each file individually to the code action proposal, which requires us to refactor the upstream code action proposal to accept custom formatting options. |
Another idea is to add two methods /**
* Sets the ICompilationUnit custom options. All and only the options explicitly included in the given table
* are remembered; all previous option settings are forgotten, including ones not explicitly
* mentioned.
* <p>
* For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
* </p>
*
* @param newOptions the new options (key type: <code>String</code>; value type: <code>String</code>),
* or <code>null</code> to flush all custom options (clients will automatically get the global JavaCore options).
* @see JavaCore#getDefaultOptions()
*/
void setOptions(Map<String, String> newOptions);
/**
* Returns the table of the current custom options for this ICompilationUnit. ICompilationUnit remember their custom options,
* in other words, only the options different from the JavaProject and JavaCore global options for the workspace.
* A boolean argument allows to directly merge the ICompilationUnit options with the project and global ones from <code>JavaCore</code>.
* <p>
* For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
* </p>
*
* @param inheritJavaCoreOptions - boolean indicating whether project and JavaCore options should be inherited as well
* @return table of current settings of all options
* (key type: <code>String</code>; value type: <code>String</code>)
* @see JavaCore#getDefaultOptions()
*/
Map<String, String> getOptions(boolean inheritJavaCoreOptions); And then let ASTRewrite.java to read the formatting from the ICompilationUnit by default. public TextEdit rewriteAST() throws JavaModelException, IllegalArgumentException {
ASTNode rootNode= getRootNode();
if (rootNode == null) {
return new MultiTextEdit(); // no changes
}
ASTNode root= rootNode.getRoot();
if (!(root instanceof CompilationUnit)) {
throw new IllegalArgumentException("This API can only be used if the AST is created from a compilation unit or class file"); //$NON-NLS-1$
}
CompilationUnit astRoot= (CompilationUnit) root;
ITypeRoot typeRoot = astRoot.getTypeRoot();
if (typeRoot == null || typeRoot.getBuffer() == null) {
throw new IllegalArgumentException("This API can only be used if the AST is created from a compilation unit or class file"); //$NON-NLS-1$
}
char[] content= typeRoot.getBuffer().getCharacters();
LineInformation lineInfo= LineInformation.create(astRoot);
String lineDelim= typeRoot.findRecommendedLineSeparator();
// =====> Add new code here
Map options = typeRoot instanceof ICompilationUnit) ? ((ICompilationUnit) typeRoot).getOptions(true) :
typeRoot.getJavaProject().getOptions(true);
return internalRewriteAST(content, lineInfo, lineDelim, astRoot.getCommentList(), options, rootNode, (RecoveryScannerData)astRoot.getStatementsRecoveryData());
} This approach has the minimal code changes on the upstream JDT code. |
That seems to be a more feasible solution. |
Created an issue https://bugs.eclipse.org/bugs/show_bug.cgi?id=569336 in upstream to discuss about supporting custom formatting options at file granularity. |
See #1151 (comment):
@jdneo @testforstephen @akaroml any volunteer?
The text was updated successfully, but these errors were encountered: