Version 2.17.0-109.0.dev
Merge commit '7a0f27f24198b8189dcc3ddb53d413cb0feedbd3' into 'dev'
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 4e9864a..7b19889 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -3118,6 +3118,7 @@
+
<dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
<p>
A directive to begin overlaying the contents of a file. The supplied
@@ -3479,6 +3480,27 @@
The label associated with this range that should be displayed to the
user.
</p>
+ </dd></dl></dd><dt class="typeDefinition"><a name="type_CompletionCaseMatchingMode">CompletionCaseMatchingMode: String</a></dt><dd>
+ <p>
+ An enumeration of the character case matching modes that the user may set in the client.
+ </p>
+
+ <dl><dt class="value">FIRST_CHAR</dt><dd>
+
+ <p>
+ Match the first character case only when filtering completions, the default for this
+ enumeration.
+ </p>
+ </dd><dt class="value">ALL_CHARS</dt><dd>
+
+ <p>
+ Match all character cases when filtering completion lists.
+ </p>
+ </dd><dt class="value">NONE</dt><dd>
+
+ <p>
+ Do not match character cases when filtering completion lists.
+ </p>
</dd></dl></dd><dt class="typeDefinition"><a name="type_CompletionId">CompletionId: String</a></dt><dd>
<p>
@@ -6116,7 +6138,7 @@
TODO: TBD
</p>
<h2 class="domain"><a name="index">Index</a></h2>
-<h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li><li><a href="#request_server.cancelRequest">cancelRequest</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.log">log</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.closingLabels">closingLabels</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li><li><a href="#request_completion.setSubscriptions">setSubscriptions</a></li><li><a href="#request_completion.registerLibraryPaths">registerLibraryPaths</a></li><li><a href="#request_completion.getSuggestionDetails">getSuggestionDetails</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li><li><a href="#notification_completion.availableSuggestions">availableSuggestions</a></li><li><a href="#notification_completion.existingImports">existingImports</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getPostfixCompletion">getPostfixCompletion</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.getSuggestions">getSuggestions</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li><li><a href="#request_diagnostic.getServerPort">getServerPort</a></li></ul></div><h4>flutter (<a href="#domain_flutter">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_flutter.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_flutter.outline">outline</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_AvailableSuggestion">AvailableSuggestion</a></li><li><a href="#type_AvailableSuggestionRelevanceTag">AvailableSuggestionRelevanceTag</a></li><li><a href="#type_AvailableSuggestionSet">AvailableSuggestionSet</a></li><li><a href="#type_BulkFix">BulkFix</a></li><li><a href="#type_BulkFixDetail">BulkFixDetail</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_ClosingLabel">ClosingLabel</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionMode">CompletionMode</a></li><li><a href="#type_CompletionService">CompletionService</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_DiagnosticMessage">DiagnosticMessage</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementDeclaration">ElementDeclaration</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_ExistingImport">ExistingImport</a></li><li><a href="#type_ExistingImports">ExistingImports</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FlutterOutline">FlutterOutline</a></li><li><a href="#type_FlutterOutlineAttribute">FlutterOutlineAttribute</a></li><li><a href="#type_FlutterOutlineKind">FlutterOutlineKind</a></li><li><a href="#type_FlutterService">FlutterService</a></li><li><a href="#type_FlutterWidgetProperty">FlutterWidgetProperty</a></li><li><a href="#type_FlutterWidgetPropertyEditor">FlutterWidgetPropertyEditor</a></li><li><a href="#type_FlutterWidgetPropertyEditorKind">FlutterWidgetPropertyEditorKind</a></li><li><a href="#type_FlutterWidgetPropertyValue">FlutterWidgetPropertyValue</a></li><li><a href="#type_FlutterWidgetPropertyValueEnumItem">FlutterWidgetPropertyValueEnumItem</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_ImportedElementSet">ImportedElementSet</a></li><li><a href="#type_ImportedElements">ImportedElements</a></li><li><a href="#type_IncludedSuggestionRelevanceTag">IncludedSuggestionRelevanceTag</a></li><li><a href="#type_IncludedSuggestionSet">IncludedSuggestionSet</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</a></li><li><a href="#type_LibraryPathSet">LibraryPathSet</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_EXTRACT_WIDGET">EXTRACT_WIDGET</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
+<h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li><li><a href="#request_server.cancelRequest">cancelRequest</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.log">log</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.closingLabels">closingLabels</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li><li><a href="#request_completion.setSubscriptions">setSubscriptions</a></li><li><a href="#request_completion.registerLibraryPaths">registerLibraryPaths</a></li><li><a href="#request_completion.getSuggestionDetails">getSuggestionDetails</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li><li><a href="#notification_completion.availableSuggestions">availableSuggestions</a></li><li><a href="#notification_completion.existingImports">existingImports</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getPostfixCompletion">getPostfixCompletion</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.getSuggestions">getSuggestions</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li><li><a href="#request_diagnostic.getServerPort">getServerPort</a></li></ul></div><h4>flutter (<a href="#domain_flutter">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_flutter.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_flutter.outline">outline</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_AvailableSuggestion">AvailableSuggestion</a></li><li><a href="#type_AvailableSuggestionRelevanceTag">AvailableSuggestionRelevanceTag</a></li><li><a href="#type_AvailableSuggestionSet">AvailableSuggestionSet</a></li><li><a href="#type_BulkFix">BulkFix</a></li><li><a href="#type_BulkFixDetail">BulkFixDetail</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_ClosingLabel">ClosingLabel</a></li><li><a href="#type_CompletionCaseMatchingMode">CompletionCaseMatchingMode</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionMode">CompletionMode</a></li><li><a href="#type_CompletionService">CompletionService</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_DiagnosticMessage">DiagnosticMessage</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementDeclaration">ElementDeclaration</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_ExistingImport">ExistingImport</a></li><li><a href="#type_ExistingImports">ExistingImports</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FlutterOutline">FlutterOutline</a></li><li><a href="#type_FlutterOutlineAttribute">FlutterOutlineAttribute</a></li><li><a href="#type_FlutterOutlineKind">FlutterOutlineKind</a></li><li><a href="#type_FlutterService">FlutterService</a></li><li><a href="#type_FlutterWidgetProperty">FlutterWidgetProperty</a></li><li><a href="#type_FlutterWidgetPropertyEditor">FlutterWidgetPropertyEditor</a></li><li><a href="#type_FlutterWidgetPropertyEditorKind">FlutterWidgetPropertyEditorKind</a></li><li><a href="#type_FlutterWidgetPropertyValue">FlutterWidgetPropertyValue</a></li><li><a href="#type_FlutterWidgetPropertyValueEnumItem">FlutterWidgetPropertyValueEnumItem</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_ImportedElementSet">ImportedElementSet</a></li><li><a href="#type_ImportedElements">ImportedElements</a></li><li><a href="#type_IncludedSuggestionRelevanceTag">IncludedSuggestionRelevanceTag</a></li><li><a href="#type_IncludedSuggestionSet">IncludedSuggestionSet</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</a></li><li><a href="#type_LibraryPathSet">LibraryPathSet</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_EXTRACT_WIDGET">EXTRACT_WIDGET</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
</body></html>
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 3baa946..6847dd0 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -138,6 +138,8 @@
const String COMPLETION_NOTIFICATION_RESULTS_RESULTS = 'results';
const String COMPLETION_REQUEST_GET_SUGGESTIONS = 'completion.getSuggestions';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2 = 'completion.getSuggestions2';
+const String COMPLETION_REQUEST_GET_SUGGESTIONS2_COMPLETION_CASE_MATCHING_MODE =
+ 'completionCaseMatchingMode';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_COMPLETION_MODE =
'completionMode';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_FILE = 'file';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 98395e9..d5a90a6 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -4215,6 +4215,68 @@
);
}
+/// CompletionCaseMatchingMode
+///
+/// enum {
+/// FIRST_CHAR
+/// ALL_CHARS
+/// NONE
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class CompletionCaseMatchingMode implements Enum {
+ /// Match the first character case only when filtering completions, the
+ /// default for this enumeration.
+ static const CompletionCaseMatchingMode FIRST_CHAR =
+ CompletionCaseMatchingMode._('FIRST_CHAR');
+
+ /// Match all character cases when filtering completion lists.
+ static const CompletionCaseMatchingMode ALL_CHARS =
+ CompletionCaseMatchingMode._('ALL_CHARS');
+
+ /// Do not match character cases when filtering completion lists.
+ static const CompletionCaseMatchingMode NONE =
+ CompletionCaseMatchingMode._('NONE');
+
+ /// A list containing all of the enum values that are defined.
+ static const List<CompletionCaseMatchingMode> VALUES =
+ <CompletionCaseMatchingMode>[FIRST_CHAR, ALL_CHARS, NONE];
+
+ @override
+ final String name;
+
+ const CompletionCaseMatchingMode._(this.name);
+
+ factory CompletionCaseMatchingMode(String name) {
+ switch (name) {
+ case 'FIRST_CHAR':
+ return FIRST_CHAR;
+ case 'ALL_CHARS':
+ return ALL_CHARS;
+ case 'NONE':
+ return NONE;
+ }
+ throw Exception('Illegal enum value: $name');
+ }
+
+ factory CompletionCaseMatchingMode.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object? json) {
+ if (json is String) {
+ try {
+ return CompletionCaseMatchingMode(json);
+ } catch (_) {
+ // Fall through
+ }
+ }
+ throw jsonDecoder.mismatch(jsonPath, 'CompletionCaseMatchingMode', json);
+ }
+
+ @override
+ String toString() => 'CompletionCaseMatchingMode.$name';
+
+ String toJson() => name;
+}
+
/// completion.existingImports params
///
/// {
@@ -4683,6 +4745,7 @@
/// "file": FilePath
/// "offset": int
/// "maxResults": int
+/// "completionCaseMatchingMode": optional CompletionCaseMatchingMode
/// }
///
/// Clients may not extend, implement or mix-in this class.
@@ -4698,6 +4761,10 @@
/// to true.
int maxResults;
+ /// The mode of code completion being invoked. If no value is provided,
+ /// MATCH_FIRST_CHAR will be assumed.
+ CompletionCaseMatchingMode? completionCaseMatchingMode;
+
/// The mode of code completion being invoked. If no value is provided, BASIC
/// will be assumed. BASIC is also the only currently supported.
CompletionMode? completionMode;
@@ -4714,7 +4781,10 @@
int? timeout;
CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults,
- {this.completionMode, this.invocationCount, this.timeout});
+ {this.completionCaseMatchingMode,
+ this.completionMode,
+ this.invocationCount,
+ this.timeout});
factory CompletionGetSuggestions2Params.fromJson(
JsonDecoder jsonDecoder, String jsonPath, Object? json) {
@@ -4739,6 +4809,13 @@
} else {
throw jsonDecoder.mismatch(jsonPath, 'maxResults');
}
+ CompletionCaseMatchingMode? completionCaseMatchingMode;
+ if (json.containsKey('completionCaseMatchingMode')) {
+ completionCaseMatchingMode = CompletionCaseMatchingMode.fromJson(
+ jsonDecoder,
+ jsonPath + '.completionCaseMatchingMode',
+ json['completionCaseMatchingMode']);
+ }
CompletionMode? completionMode;
if (json.containsKey('completionMode')) {
completionMode = CompletionMode.fromJson(
@@ -4754,6 +4831,7 @@
timeout = jsonDecoder.decodeInt(jsonPath + '.timeout', json['timeout']);
}
return CompletionGetSuggestions2Params(file, offset, maxResults,
+ completionCaseMatchingMode: completionCaseMatchingMode,
completionMode: completionMode,
invocationCount: invocationCount,
timeout: timeout);
@@ -4774,6 +4852,11 @@
result['file'] = file;
result['offset'] = offset;
result['maxResults'] = maxResults;
+ var completionCaseMatchingMode = this.completionCaseMatchingMode;
+ if (completionCaseMatchingMode != null) {
+ result['completionCaseMatchingMode'] =
+ completionCaseMatchingMode.toJson();
+ }
var completionMode = this.completionMode;
if (completionMode != null) {
result['completionMode'] = completionMode.toJson();
@@ -4803,6 +4886,7 @@
return file == other.file &&
offset == other.offset &&
maxResults == other.maxResults &&
+ completionCaseMatchingMode == other.completionCaseMatchingMode &&
completionMode == other.completionMode &&
invocationCount == other.invocationCount &&
timeout == other.timeout;
@@ -4815,6 +4899,7 @@
file,
offset,
maxResults,
+ completionCaseMatchingMode,
completionMode,
invocationCount,
timeout,
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index c12b23d..fddcbfa 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -993,6 +993,11 @@
/// suggestions after filtering is greater than the maxResults, then
/// isIncomplete is set to true.
///
+ /// completionCaseMatchingMode: CompletionCaseMatchingMode (optional)
+ ///
+ /// The mode of code completion being invoked. If no value is provided,
+ /// MATCH_FIRST_CHAR will be assumed.
+ ///
/// Returns
///
/// replacementOffset: int
@@ -1029,10 +1034,12 @@
/// requested maxResults.
Future<CompletionGetSuggestions2Result> sendCompletionGetSuggestions2(
String file, int offset, int maxResults,
- {CompletionMode? completionMode,
+ {CompletionCaseMatchingMode? completionCaseMatchingMode,
+ CompletionMode? completionMode,
int? invocationCount,
int? timeout}) async {
var params = CompletionGetSuggestions2Params(file, offset, maxResults,
+ completionCaseMatchingMode: completionCaseMatchingMode,
completionMode: completionMode,
invocationCount: invocationCount,
timeout: timeout)
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 3e1ed40..ddf2b9b 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -230,6 +230,16 @@
final Matcher isClosingLabel = LazyMatcher(() => MatchesJsonObject(
'ClosingLabel', {'offset': isInt, 'length': isInt, 'label': isString}));
+/// CompletionCaseMatchingMode
+///
+/// enum {
+/// FIRST_CHAR
+/// ALL_CHARS
+/// NONE
+/// }
+final Matcher isCompletionCaseMatchingMode = MatchesEnum(
+ 'CompletionCaseMatchingMode', ['FIRST_CHAR', 'ALL_CHARS', 'NONE']);
+
/// CompletionId
///
/// String
@@ -2148,17 +2158,19 @@
/// "file": FilePath
/// "offset": int
/// "maxResults": int
+/// "completionCaseMatchingMode": optional CompletionCaseMatchingMode
/// }
-final Matcher isCompletionGetSuggestions2Params = LazyMatcher(() =>
- MatchesJsonObject('completion.getSuggestions2 params', {
- 'file': isFilePath,
- 'offset': isInt,
- 'maxResults': isInt
- }, optionalFields: {
- 'completionMode': isCompletionMode,
- 'invocationCount': isInt,
- 'timeout': isInt
- }));
+final Matcher isCompletionGetSuggestions2Params =
+ LazyMatcher(() => MatchesJsonObject('completion.getSuggestions2 params', {
+ 'file': isFilePath,
+ 'offset': isInt,
+ 'maxResults': isInt
+ }, optionalFields: {
+ 'completionCaseMatchingMode': isCompletionCaseMatchingMode,
+ 'completionMode': isCompletionMode,
+ 'invocationCount': isInt,
+ 'timeout': isInt
+ }));
/// completion.getSuggestions2 result
///
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 3d8e563..59da953 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -440,6 +440,8 @@
* @param offset The offset within the file at which suggestions are to be made.
* @param maxResults The maximum number of suggestions to return. If the number of suggestions
* after filtering is greater than the maxResults, then isIncomplete is set to true.
+ * @param completionCaseMatchingMode The mode of code completion being invoked. If no value is
+ * provided, MATCH_FIRST_CHAR will be assumed.
* @param completionMode The mode of code completion being invoked. If no value is provided, BASIC
* will be assumed. BASIC is also the only currently supported.
* @param invocationCount The number of times that the user has invoked code completion at the same
@@ -449,7 +451,7 @@
* field is intended to be used for benchmarking, and usually should not be provided, so
* that the default timeout is used.
*/
- public void completion_getSuggestions2(String file, int offset, int maxResults, String completionMode, int invocationCount, int timeout, GetSuggestions2Consumer consumer);
+ public void completion_getSuggestions2(String file, int offset, int maxResults, String completionCaseMatchingMode, String completionMode, int invocationCount, int timeout, GetSuggestions2Consumer consumer);
/**
* {@code completion.registerLibraryPaths}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionCaseMatchingMode.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionCaseMatchingMode.java
new file mode 100644
index 0000000..3a4dc2a
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionCaseMatchingMode.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+/**
+ * An enumeration of the character case matching modes that the user may set in the client.
+ *
+ * @coverage dart.server.generated.types
+ */
+public class CompletionCaseMatchingMode {
+
+ /**
+ * Match the first character case only when filtering completions, the default for this
+ * enumeration.
+ */
+ public static final String FIRST_CHAR = "FIRST_CHAR";
+
+ /**
+ * Match all character cases when filtering completion lists.
+ */
+ public static final String ALL_CHARS = "ALL_CHARS";
+
+ /**
+ * Do not match character cases when filtering completion lists.
+ */
+ public static final String NONE = "NONE";
+
+}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 51f35a4..7210871 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1507,6 +1507,13 @@
then <tt>isIncomplete</tt> is set to <tt>true</tt>.
</p>
</field>
+ <field name="completionCaseMatchingMode" optional="true">
+ <ref>CompletionCaseMatchingMode</ref>
+ <p>
+ The mode of code completion being invoked. If no value is provided,
+ <tt>MATCH_FIRST_CHAR</tt> will be assumed.
+ </p>
+ </field>
<field name="completionMode" experimental="true" optional="true">
<ref>CompletionMode</ref>
<p>
@@ -4146,6 +4153,32 @@
</value>
</enum>
</type>
+ <type name="CompletionCaseMatchingMode">
+ <p>
+ An enumeration of the character case matching modes that the user may set in the client.
+ </p>
+ <enum>
+ <value>
+ <code>FIRST_CHAR</code>
+ <p>
+ Match the first character case only when filtering completions, the default for this
+ enumeration.
+ </p>
+ </value>
+ <value>
+ <code>ALL_CHARS</code>
+ <p>
+ Match all character cases when filtering completion lists.
+ </p>
+ </value>
+ <value>
+ <code>NONE</code>
+ <p>
+ Do not match character cases when filtering completion lists.
+ </p>
+ </value>
+ </enum>
+ </type>
<type name="RuntimeCompletionExpression">
<p>
An expression for which we want to know its runtime type.
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 3baa946..6847dd0 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -138,6 +138,8 @@
const String COMPLETION_NOTIFICATION_RESULTS_RESULTS = 'results';
const String COMPLETION_REQUEST_GET_SUGGESTIONS = 'completion.getSuggestions';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2 = 'completion.getSuggestions2';
+const String COMPLETION_REQUEST_GET_SUGGESTIONS2_COMPLETION_CASE_MATCHING_MODE =
+ 'completionCaseMatchingMode';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_COMPLETION_MODE =
'completionMode';
const String COMPLETION_REQUEST_GET_SUGGESTIONS2_FILE = 'file';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index 413c551..484915e 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -4215,6 +4215,68 @@
);
}
+/// CompletionCaseMatchingMode
+///
+/// enum {
+/// FIRST_CHAR
+/// ALL_CHARS
+/// NONE
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class CompletionCaseMatchingMode implements Enum {
+ /// Match the first character case only when filtering completions, the
+ /// default for this enumeration.
+ static const CompletionCaseMatchingMode FIRST_CHAR =
+ CompletionCaseMatchingMode._('FIRST_CHAR');
+
+ /// Match all character cases when filtering completion lists.
+ static const CompletionCaseMatchingMode ALL_CHARS =
+ CompletionCaseMatchingMode._('ALL_CHARS');
+
+ /// Do not match character cases when filtering completion lists.
+ static const CompletionCaseMatchingMode NONE =
+ CompletionCaseMatchingMode._('NONE');
+
+ /// A list containing all of the enum values that are defined.
+ static const List<CompletionCaseMatchingMode> VALUES =
+ <CompletionCaseMatchingMode>[FIRST_CHAR, ALL_CHARS, NONE];
+
+ @override
+ final String name;
+
+ const CompletionCaseMatchingMode._(this.name);
+
+ factory CompletionCaseMatchingMode(String name) {
+ switch (name) {
+ case 'FIRST_CHAR':
+ return FIRST_CHAR;
+ case 'ALL_CHARS':
+ return ALL_CHARS;
+ case 'NONE':
+ return NONE;
+ }
+ throw Exception('Illegal enum value: $name');
+ }
+
+ factory CompletionCaseMatchingMode.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object? json) {
+ if (json is String) {
+ try {
+ return CompletionCaseMatchingMode(json);
+ } catch (_) {
+ // Fall through
+ }
+ }
+ throw jsonDecoder.mismatch(jsonPath, 'CompletionCaseMatchingMode', json);
+ }
+
+ @override
+ String toString() => 'CompletionCaseMatchingMode.$name';
+
+ String toJson() => name;
+}
+
/// completion.existingImports params
///
/// {
@@ -4683,6 +4745,7 @@
/// "file": FilePath
/// "offset": int
/// "maxResults": int
+/// "completionCaseMatchingMode": optional CompletionCaseMatchingMode
/// }
///
/// Clients may not extend, implement or mix-in this class.
@@ -4698,6 +4761,10 @@
/// to true.
int maxResults;
+ /// The mode of code completion being invoked. If no value is provided,
+ /// MATCH_FIRST_CHAR will be assumed.
+ CompletionCaseMatchingMode? completionCaseMatchingMode;
+
/// The mode of code completion being invoked. If no value is provided, BASIC
/// will be assumed. BASIC is also the only currently supported.
CompletionMode? completionMode;
@@ -4714,7 +4781,10 @@
int? timeout;
CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults,
- {this.completionMode, this.invocationCount, this.timeout});
+ {this.completionCaseMatchingMode,
+ this.completionMode,
+ this.invocationCount,
+ this.timeout});
factory CompletionGetSuggestions2Params.fromJson(
JsonDecoder jsonDecoder, String jsonPath, Object? json) {
@@ -4739,6 +4809,13 @@
} else {
throw jsonDecoder.mismatch(jsonPath, 'maxResults');
}
+ CompletionCaseMatchingMode? completionCaseMatchingMode;
+ if (json.containsKey('completionCaseMatchingMode')) {
+ completionCaseMatchingMode = CompletionCaseMatchingMode.fromJson(
+ jsonDecoder,
+ jsonPath + '.completionCaseMatchingMode',
+ json['completionCaseMatchingMode']);
+ }
CompletionMode? completionMode;
if (json.containsKey('completionMode')) {
completionMode = CompletionMode.fromJson(
@@ -4754,6 +4831,7 @@
timeout = jsonDecoder.decodeInt(jsonPath + '.timeout', json['timeout']);
}
return CompletionGetSuggestions2Params(file, offset, maxResults,
+ completionCaseMatchingMode: completionCaseMatchingMode,
completionMode: completionMode,
invocationCount: invocationCount,
timeout: timeout);
@@ -4774,6 +4852,11 @@
result['file'] = file;
result['offset'] = offset;
result['maxResults'] = maxResults;
+ var completionCaseMatchingMode = this.completionCaseMatchingMode;
+ if (completionCaseMatchingMode != null) {
+ result['completionCaseMatchingMode'] =
+ completionCaseMatchingMode.toJson();
+ }
var completionMode = this.completionMode;
if (completionMode != null) {
result['completionMode'] = completionMode.toJson();
@@ -4803,6 +4886,7 @@
return file == other.file &&
offset == other.offset &&
maxResults == other.maxResults &&
+ completionCaseMatchingMode == other.completionCaseMatchingMode &&
completionMode == other.completionMode &&
invocationCount == other.invocationCount &&
timeout == other.timeout;
@@ -4815,6 +4899,7 @@
file,
offset,
maxResults,
+ completionCaseMatchingMode,
completionMode,
invocationCount,
timeout,
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 271c7c6..9491945 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -31,7 +31,6 @@
import 'elements/entities.dart';
import 'enqueue.dart' show Enqueuer, EnqueueTask, ResolutionEnqueuer;
import 'environment.dart';
-import 'frontend_strategy.dart';
import 'inferrer/abstract_value_domain.dart' show AbstractValueStrategy;
import 'inferrer/trivial.dart' show TrivialAbstractValueStrategy;
import 'inferrer/powersets/wrapped.dart' show WrappedAbstractValueStrategy;
@@ -71,7 +70,7 @@
final api.CompilerInput provider;
final api.CompilerDiagnostics handler;
- FrontendStrategy frontendStrategy;
+ KernelFrontendStrategy frontendStrategy;
BackendStrategy backendStrategy;
CompilerDiagnosticReporter _reporter;
Map<Entity, WorldImpact> _impactCache;
@@ -455,7 +454,6 @@
processQueue(
frontendStrategy.elementEnvironment, resolutionEnqueuer, mainFunction,
onProgress: showResolutionProgress);
- frontendStrategy.onResolutionEnd();
resolutionEnqueuer.logSummary(reporter.log);
_reporter.reportSuppressedMessagesSummary();
@@ -477,7 +475,7 @@
.addAll(result.moduleLibraries.map((module) => CodeLocation(module)));
selfTask.measureSubtask('runModularAnalysis', () {
var included = result.moduleLibraries.toSet();
- var elementMap = (frontendStrategy as KernelFrontendStrategy).elementMap;
+ var elementMap = frontendStrategy.elementMap;
var moduleData = computeModuleData(result.component, included, options,
reporter, environment, elementMap);
if (compilationFailed) return;
diff --git a/pkg/compiler/lib/src/frontend_strategy.dart b/pkg/compiler/lib/src/frontend_strategy.dart
deleted file mode 100644
index 3fc6ccc..0000000
--- a/pkg/compiler/lib/src/frontend_strategy.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.frontend_strategy;
-
-import 'common.dart';
-import 'common/elements.dart';
-import 'common/tasks.dart';
-import 'compiler.dart' show Compiler;
-import 'deferred_load/deferred_load.dart' show DeferredLoadTask;
-import 'elements/entities.dart';
-import 'enqueue.dart';
-import 'ir/modular.dart';
-import 'js_backend/native_data.dart';
-import 'js_backend/no_such_method_registry.dart';
-import 'kernel/loader.dart';
-import 'universe/world_impact.dart';
-
-/// Strategy pattern that defines the connection between the input format and
-/// the resolved element model.
-abstract class FrontendStrategy {
- /// Registers a set of loaded libraries with this strategy.
- void registerLoadedLibraries(KernelResult result);
-
- void registerModuleData(List<ModuleData> data);
-
- /// Returns the [ElementEnvironment] for the element model used in this
- /// strategy.
- ElementEnvironment get elementEnvironment;
-
- /// Returns the [CommonElements] for the element model used in this
- /// strategy.
- CommonElements get commonElements;
-
- NativeBasicData get nativeBasicData;
-
- /// Creates a [DeferredLoadTask] for the element model used in this strategy.
- DeferredLoadTask createDeferredLoadTask(Compiler compiler);
-
- /// Support for classifying `noSuchMethod` implementations.
- NoSuchMethodRegistry get noSuchMethodRegistry;
-
- /// Called before processing of the resolution queue is started.
- void onResolutionStart();
-
- ResolutionEnqueuer createResolutionEnqueuer(
- CompilerTask task, Compiler compiler);
-
- /// Called when the resolution queue has been closed.
- void onResolutionEnd();
-
- /// Computes the main function from [mainLibrary] adding additional world
- /// impact to [impactBuilder].
- FunctionEntity computeMain(WorldImpactBuilder impactBuilder);
-
- /// Creates a [SourceSpan] from [spannable] in context of [currentElement].
- SourceSpan spanFromSpannable(Spannable spannable, Entity currentElement);
-}
-
-/// Class that performs the mechanics to investigate annotations in the code.
-abstract class AnnotationProcessor {
- void extractNativeAnnotations(LibraryEntity library);
-
- void extractJsInteropAnnotations(LibraryEntity library);
-}
diff --git a/pkg/compiler/lib/src/js_backend/backend_usage.dart b/pkg/compiler/lib/src/js_backend/backend_usage.dart
index 6f87f10..08f17ce 100644
--- a/pkg/compiler/lib/src/js_backend/backend_usage.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_usage.dart
@@ -6,8 +6,8 @@
import '../common/elements.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
-import '../frontend_strategy.dart';
import '../ir/runtime_type_analysis.dart';
+import '../kernel/kernel_strategy.dart';
import '../serialization/serialization.dart';
import '../universe/feature.dart';
import '../util/util.dart' show Setlet;
@@ -104,7 +104,7 @@
}
class BackendUsageBuilderImpl implements BackendUsageBuilder {
- final FrontendStrategy _frontendStrategy;
+ final KernelFrontendStrategy _frontendStrategy;
// TODO(johnniwinther): Remove the need for these.
Setlet<FunctionEntity> _globalFunctionDependencies;
Setlet<ClassEntity> _globalClassDependencies;
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index ba76698..c4d6943 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -22,7 +22,6 @@
import '../elements/names.dart';
import '../elements/types.dart';
import '../environment.dart';
-import '../frontend_strategy.dart';
import '../ir/annotations.dart';
import '../ir/constants.dart';
import '../ir/element_map.dart';
@@ -39,6 +38,7 @@
import '../js_backend/namer.dart';
import '../js_backend/native_data.dart';
import '../js_model/locals.dart';
+import '../kernel/kernel_strategy.dart';
import '../kernel/dart2js_target.dart';
import '../native/behavior.dart';
import '../native/resolver.dart';
@@ -103,7 +103,7 @@
final Map<ir.TreeNode, Local> localFunctionMap = {};
BehaviorBuilder _nativeBehaviorBuilder;
- final FrontendStrategy _frontendStrategy;
+ final KernelFrontendStrategy _frontendStrategy;
Map<KMember, Map<ir.Expression, TypeMap>> typeMapsForTesting;
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index 8cebfcb..dcd7fb2 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -18,7 +18,6 @@
import '../elements/entities.dart';
import '../enqueue.dart';
import '../environment.dart' as env;
-import '../frontend_strategy.dart';
import '../ir/annotations.dart';
import '../ir/closure.dart' show ClosureScopeModel;
import '../ir/impact.dart';
@@ -52,7 +51,7 @@
/// Front end strategy that loads '.dill' files and builds a resolved element
/// model from kernel IR nodes.
-class KernelFrontendStrategy extends FrontendStrategy {
+class KernelFrontendStrategy {
final NativeBasicDataBuilderImpl nativeBasicDataBuilder =
NativeBasicDataBuilderImpl();
NativeBasicData _nativeBasicData;
@@ -81,7 +80,7 @@
KFieldAnalysis _fieldAnalysis;
- @override
+ /// Support for classifying `noSuchMethod` implementations.
NoSuchMethodRegistry noSuchMethodRegistry;
KernelFrontendStrategy(this._compilerTask, this._options,
@@ -99,7 +98,7 @@
KFieldAnalysis get fieldAnalysisForTesting => _fieldAnalysis;
- @override
+ /// Called before processing of the resolution queue is started.
void onResolutionStart() {
// TODO(johnniwinther): Avoid the compiler.elementEnvironment.getThisType
// calls. Currently needed to ensure resolution of the classes for various
@@ -134,7 +133,6 @@
});
}
- @override
ResolutionEnqueuer createResolutionEnqueuer(
CompilerTask task, Compiler compiler) {
RuntimeTypesNeedBuilder rtiNeedBuilder = _createRuntimeTypesNeedBuilder();
@@ -223,10 +221,6 @@
annotationsData);
}
- @override
- void onResolutionEnd() {}
-
- @override
NativeBasicData get nativeBasicData {
if (_nativeBasicData == null) {
_nativeBasicData = nativeBasicDataBuilder.close(elementEnvironment);
@@ -238,7 +232,7 @@
return _nativeBasicData;
}
- @override
+ /// Registers a set of loaded libraries with this strategy.
void registerLoadedLibraries(KernelResult kernelResult) {
_elementMap.addComponent(kernelResult.component);
_irAnnotationData = processAnnotations(
@@ -257,7 +251,6 @@
}
}
- @override
void registerModuleData(List<ModuleData> data) {
if (data == null) {
_modularStrategy = KernelModularStrategy(_compilerTask, _elementMap);
@@ -271,19 +264,23 @@
ModularStrategy get modularStrategyForTesting => _modularStrategy;
- @override
- ElementEnvironment get elementEnvironment => _elementMap.elementEnvironment;
+ /// Returns the [ElementEnvironment] for the element model used in this
+ /// strategy.
+ KernelElementEnvironment get elementEnvironment =>
+ _elementMap.elementEnvironment;
- @override
- CommonElements get commonElements => _elementMap.commonElements;
+ /// Returns the [CommonElements] for the element model used in this
+ /// strategy.
+ KCommonElements get commonElements => _elementMap.commonElements;
KernelToElementMap get elementMap => _elementMap;
- @override
+ /// Creates a [DeferredLoadTask] for the element model used in this strategy.
DeferredLoadTask createDeferredLoadTask(Compiler compiler) =>
DeferredLoadTask(compiler, _elementMap);
- @override
+ /// Computes the main function from [mainLibrary] adding additional world
+ /// impact to [impactBuilder].
FunctionEntity computeMain(WorldImpactBuilder impactBuilder) {
return elementEnvironment.mainFunction;
}
@@ -297,7 +294,7 @@
RuntimeTypesNeedBuilder get runtimeTypesNeedBuilderForTesting =>
_runtimeTypesNeedBuilder;
- @override
+ /// Creates a [SourceSpan] from [spannable] in context of [currentElement].
SourceSpan spanFromSpannable(Spannable spannable, Entity currentElement) {
return _elementMap.getSourceSpan(spannable, currentElement);
}
diff --git a/pkg/compiler/lib/src/kernel/native_basic_data.dart b/pkg/compiler/lib/src/kernel/native_basic_data.dart
index d058403..ed4a83d 100644
--- a/pkg/compiler/lib/src/kernel/native_basic_data.dart
+++ b/pkg/compiler/lib/src/kernel/native_basic_data.dart
@@ -8,14 +8,13 @@
import '../common/elements.dart';
import '../constants/values.dart';
import '../elements/entities.dart';
-import '../frontend_strategy.dart';
import '../ir/annotations.dart';
import '../js_backend/native_data.dart';
import '../native/resolver.dart';
import 'element_map_impl.dart';
-class KernelAnnotationProcessor implements AnnotationProcessor {
+class KernelAnnotationProcessor {
final KernelToElementMapImpl elementMap;
final NativeBasicDataBuilder _nativeBasicDataBuilder;
final IrAnnotationData annotationData;
@@ -24,7 +23,6 @@
this.elementMap, this._nativeBasicDataBuilder, this.annotationData)
: assert(annotationData != null);
- @override
void extractNativeAnnotations(LibraryEntity library) {
KElementEnvironment elementEnvironment = elementMap.elementEnvironment;
@@ -57,7 +55,6 @@
return annotationName;
}
- @override
void extractJsInteropAnnotations(LibraryEntity library) {
// Unused reporter, add back in if uncommenting report lines down below.
// DiagnosticReporter reporter = elementMap.reporter;
diff --git a/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart b/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart
index 2c20593..b8dcd74 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart
@@ -49,6 +49,9 @@
}
@override
+ bool validPostcondition(HGraph graph) => true;
+
+ @override
visitBasicBlock(HBasicBlock node) {
HInstruction instruction = node.first;
while (instruction != null) {
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index b52be9d..c474639 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -47,6 +47,9 @@
}
@override
+ bool validPostcondition(HGraph graph) => true;
+
+ @override
void visitBasicBlock(HBasicBlock node) {
currentBlock = node;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index fe51fdd..d7433a0 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -39,12 +39,14 @@
import 'nodes.dart';
import 'types.dart';
import 'types_propagation.dart';
+import 'validate.dart' show NoUnusedPhiValidator;
import 'value_range_analyzer.dart';
import 'value_set.dart';
abstract class OptimizationPhase {
String get name;
void visitGraph(HGraph graph);
+ bool validPostcondition(HGraph graph);
}
class SsaOptimizerTask extends CompilerTask {
@@ -70,6 +72,8 @@
measureSubtask(phase.name, () => phase.visitGraph(graph));
codegen.tracer.traceGraph(phase.name, graph);
assert(graph.isValid(), 'Graph not valid after ${phase.name}');
+ assert(phase.validPostcondition(graph),
+ 'Graph does not satify phase postcondition after ${phase.name}');
}
SsaCodeMotion codeMotion;
@@ -244,6 +248,9 @@
}
@override
+ bool validPostcondition(HGraph graph) => true;
+
+ @override
visitBasicBlock(HBasicBlock block) {
simplifyPhis(block);
HInstruction instruction = block.first;
@@ -2518,6 +2525,11 @@
}
@override
+ bool validPostcondition(HGraph graph) {
+ return NoUnusedPhiValidator.containsNoUnusedPhis(graph);
+ }
+
+ @override
void visitBasicBlock(HBasicBlock block) {
bool isDeadBlock = analyzer.isDeadBlock(block);
block.isLive = !isDeadBlock;
@@ -2827,27 +2839,33 @@
}
}
- // Remove phis that are not live.
- // Traverse in reverse order to remove phis with no uses before the
- // phis that they might use.
- // NOTICE: Doesn't handle circular references, but we don't currently
- // create any.
- List<HBasicBlock> blocks = graph.blocks;
- for (int i = blocks.length - 1; i >= 0; i--) {
- HBasicBlock block = blocks[i];
- HPhi current = block.phis.first;
- HPhi next = null;
- while (current != null) {
- next = current.next;
- if (!livePhis.contains(current)
- // TODO(ahe): Not sure the following is correct.
- &&
- current.usedBy.isEmpty) {
- block.removePhi(current);
- }
- current = next;
- }
+ // Collect dead phis.
+ List<HPhi> deadPhis = [];
+ for (final block in graph.blocks) {
+ block.forEachPhi((phi) {
+ if (!livePhis.contains(phi)) deadPhis.add(phi);
+ });
}
+
+ // Two-phase removal, phase 1: unlink all the input nodes.
+ for (final phi in deadPhis) {
+ for (final input in phi.inputs) {
+ input.removeUser(phi);
+ }
+ phi.inputs.clear();
+ }
+
+ // Two-phase removal, phase 2: remove the now-disconnected phis.
+ for (final phi in deadPhis) {
+ assert(phi.inputs.isEmpty);
+ assert(phi.usedBy.isEmpty);
+ phi.block.removePhi(phi);
+ }
+ }
+
+ @override
+ bool validPostcondition(HGraph graph) {
+ return NoUnusedPhiValidator.containsNoUnusedPhis(graph);
}
}
@@ -2903,6 +2921,9 @@
}
}
}
+
+ @override
+ bool validPostcondition(HGraph graph) => true;
}
class GvnWorkItem {
@@ -2933,6 +2954,9 @@
} while (!workQueue.isEmpty);
}
+ @override
+ bool validPostcondition(HGraph graph) => true;
+
void moveLoopInvariantCode(HGraph graph) {
for (int i = graph.blocks.length - 1; i >= 0; i--) {
HBasicBlock block = graph.blocks[i];
@@ -3158,6 +3182,9 @@
}
@override
+ bool validPostcondition(HGraph graph) => true;
+
+ @override
void visitBasicBlock(HBasicBlock block) {
List<HBasicBlock> successors = block.successors;
@@ -3261,6 +3288,9 @@
visitDominatorTree(graph);
}
+ @override
+ bool validPostcondition(HGraph graph) => true;
+
// Update users of [input] that are dominated by [:dominator.first:]
// to use [TypeKnown] of [input] instead. As the type information depends
// on the control flow, we mark the inserted [HTypeKnown] nodes as
@@ -3444,6 +3474,9 @@
}
@override
+ bool validPostcondition(HGraph graph) => true;
+
+ @override
void visitBasicBlock(HBasicBlock block) {
final predecessors = block.predecessors;
final indegree = predecessors.length;
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index a8ff036..5a88ac3 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -71,6 +71,9 @@
}
@override
+ bool validPostcondition(HGraph graph) => true;
+
+ @override
visitBasicBlock(HBasicBlock block) {
if (block.isLoopHeader()) {
block.forEachPhi((HPhi phi) {
diff --git a/pkg/compiler/lib/src/ssa/validate.dart b/pkg/compiler/lib/src/ssa/validate.dart
index 251368b..04c7f00 100644
--- a/pkg/compiler/lib/src/ssa/validate.dart
+++ b/pkg/compiler/lib/src/ssa/validate.dart
@@ -220,3 +220,28 @@
}
}
}
+
+/// Validate that the graph contains no unused phi nodes.
+///
+/// assert(NoUnusedPhiValidator.containsNoUnusedPhis(graph));
+class NoUnusedPhiValidator extends HGraphVisitor {
+ bool isValid = true;
+
+ static bool containsNoUnusedPhis(HGraph graph) {
+ final validator = NoUnusedPhiValidator();
+ validator.visitDominatorTree(graph);
+ return validator.isValid;
+ }
+
+ @override
+ void visitBasicBlock(HBasicBlock block) {
+ block.forEachPhi(visitPhi);
+ }
+
+ void visitPhi(HPhi phi) {
+ if (phi.usedBy.isEmpty) {
+ print('Unused $phi in B${phi.block.id}');
+ isValid = false;
+ }
+ }
+}
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index 2b20fa4..d84928d 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -665,6 +665,9 @@
optimizer.ranges = ranges;
}
+ @override
+ bool validPostcondition(HGraph graph) => true;
+
void removeRangeConversion() {
conversions.forEach((HRangeConversion instruction) {
instruction.block.rewrite(instruction, instruction.inputs[0]);
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index 1038d97..c171029 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -242,6 +242,7 @@
alwaysNullableType,
angularAnnotation,
argumentErrorCheckNotNull,
+ builtValueNullableAnnotation,
callTearOff,
compoundAssignment,
// See [DummyOrigin].
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index bac0513..164c4aa 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -29,6 +29,7 @@
import 'package:nnbd_migration/src/expression_checks.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/nullability_node_target.dart';
+import 'package:nnbd_migration/src/utilities/built_value_transformer.dart';
import 'package:nnbd_migration/src/utilities/completeness_tracker.dart';
import 'package:nnbd_migration/src/utilities/hint_utils.dart';
import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
@@ -1330,6 +1331,14 @@
@override
DecoratedType? visitMethodDeclaration(MethodDeclaration node) {
+ if (BuiltValueTransformer.findNullableAnnotation(node) != null) {
+ _graph.makeNullable(
+ _variables!
+ .decoratedElementType(node.declaredElement!.declaration)
+ .returnType!
+ .node!,
+ BuiltValueNullableOrigin(source, node));
+ }
_handleExecutableDeclaration(node, node.declaredElement!, node.metadata,
node.returnType, node.parameters, null, node.body, null);
_dispatch(node.typeParameters);
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index 58ffe89..ff7d8ce 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -98,6 +98,17 @@
EdgeOriginKind get kind => EdgeOriginKind.argumentErrorCheckNotNull;
}
+/// Edge origin resulting from a use of built_value's `@nullable` annotation.
+class BuiltValueNullableOrigin extends EdgeOrigin {
+ BuiltValueNullableOrigin(Source? source, AstNode node) : super(source, node);
+
+ @override
+ String get description => 'method is marked with the `@nullable` annotation';
+
+ @override
+ EdgeOriginKind get kind => EdgeOriginKind.builtValueNullableAnnotation;
+}
+
/// An edge origin used for edges that originated because of a tear-off of
/// `call` on a function type.
class CallTearOffOrigin extends EdgeOrigin {
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index e46d892..8ebe8d5 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -35,6 +35,7 @@
import 'package:nnbd_migration/src/edit_plan.dart';
import 'package:nnbd_migration/src/fix_aggregator.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:nnbd_migration/src/utilities/built_value_transformer.dart';
import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
import 'package:nnbd_migration/src/utilities/resolution_utils.dart';
import 'package:nnbd_migration/src/utilities/where_or_null_transformer.dart';
@@ -1245,25 +1246,13 @@
@override
void visitMethodDeclaration(MethodDeclaration node) {
- if (node.isGetter && node.isAbstract) {
- for (var annotation in node.metadata) {
- if (annotation.arguments == null) {
- var element = annotation.element;
- if (element is PropertyAccessorElement &&
- element.name == 'nullable') {
- if (element.enclosingElement is CompilationUnitElement) {
- if (element.library.source.uri.toString() ==
- 'package:built_value/built_value.dart') {
- var info = AtomicEditInfo(
- NullabilityFixDescription.removeNullableAnnotation, {});
- (_fixBuilder._getChange(node) as NodeChangeForMethodDeclaration)
- ..annotationToRemove = annotation
- ..removeAnnotationInfo = info;
- }
- }
- }
- }
- }
+ var nullableAnnotation = BuiltValueTransformer.findNullableAnnotation(node);
+ if (nullableAnnotation != null) {
+ var info = AtomicEditInfo(
+ NullabilityFixDescription.removeNullableAnnotation, {});
+ (_fixBuilder._getChange(node) as NodeChangeForMethodDeclaration)
+ ..annotationToRemove = nullableAnnotation
+ ..removeAnnotationInfo = info;
}
super.visitMethodDeclaration(node);
}
diff --git a/pkg/nnbd_migration/lib/src/utilities/built_value_transformer.dart b/pkg/nnbd_migration/lib/src/utilities/built_value_transformer.dart
new file mode 100644
index 0000000..c4ed06f
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/utilities/built_value_transformer.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+
+class BuiltValueTransformer {
+ static Annotation? findNullableAnnotation(MethodDeclaration node) {
+ if (node.isGetter && node.isAbstract) {
+ for (var annotation in node.metadata) {
+ if (annotation.arguments == null) {
+ var element = annotation.element;
+ if (element is PropertyAccessorElement &&
+ element.name == 'nullable') {
+ if (element.enclosingElement is CompilationUnitElement) {
+ if (element.library.source.uri.toString() ==
+ 'package:built_value/built_value.dart') {
+ return annotation;
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 8efdc63..de6b5bb 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -977,6 +977,26 @@
{path1: file1, path2: file2}, {path1: expected1, path2: anything});
}
+ Future<void> test_built_value_nullable_getter_interface_only() async {
+ addBuiltValuePackage();
+ var content = '''
+import 'package:built_value/built_value.dart';
+
+abstract class Foo {
+ @nullable
+ int get value;
+}
+''';
+ var expected = '''
+import 'package:built_value/built_value.dart';
+
+abstract class Foo {
+ int? get value;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_call_already_migrated_extension() async {
var content = '''
import 'already_migrated.dart';
diff --git a/pkg/vm_service/test/breakpoint_in_enhanced_enums_test.dart b/pkg/vm_service/test/breakpoint_in_enhanced_enums_test.dart
new file mode 100644
index 0000000..ebedeeb
--- /dev/null
+++ b/pkg/vm_service/test/breakpoint_in_enhanced_enums_test.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// SharedOptions=--enable-experiment=enhanced-enums
+
+// ignore_for_file: experiment_not_enabled
+// @dart=2.17
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+const int LINE_A = 24;
+const int LINE_B = LINE_A + 11;
+const int LINE_C = LINE_B + 4;
+const int LINE_D = LINE_C + 4;
+const int LINE_E = LINE_D + 5;
+const int LINE_F = LINE_E + 4;
+const int LINE_G = LINE_F + 5;
+const int LINE_H = LINE_G + 4;
+
+mixin M on Object {
+ int mixedInMethod() {
+ print('mixedInMethod'); // LINE_A
+ return 0;
+ }
+}
+
+enum E with M {
+ e1,
+ e2,
+ e3;
+
+ void instanceMethod() {
+ print('instanceMethod'); // LINE_B
+ }
+
+ static void staticMethod() {
+ print('staticMethod'); // LINE_C
+ }
+
+ int get getter {
+ print('getter'); // LINE_D
+ return 0;
+ }
+
+ set setter(int x) {
+ print('setter'); // LINE_E
+ }
+
+ static int get staticGetter {
+ print('staticGetter'); // LINE_F
+ return 0;
+ }
+
+ static set staticSetter(int x) {
+ print('staticSetter'); // LINE_G
+ }
+
+ String toString() {
+ print('overriden toString'); // LINE_H
+ return '';
+ }
+}
+
+void testMain() {
+ E.staticMethod();
+ E.staticGetter;
+ E.staticSetter = 42;
+ final e = E.e1;
+ e.mixedInMethod();
+ e.instanceMethod();
+ e.getter;
+ e.setter = 42;
+ e.toString();
+}
+
+const lines = <int>[
+ LINE_C,
+ LINE_F,
+ LINE_G,
+ LINE_A,
+ LINE_B,
+ LINE_D,
+ LINE_E,
+ LINE_H,
+];
+
+const fileName = 'breakpoint_in_enhanced_enums_test.dart';
+final expected = <String>[
+ for (final line in lines) '$fileName:$line:5',
+];
+
+final stops = <String>[];
+
+final tests = <IsolateTest>[
+ hasPausedAtStart,
+ for (final line in lines) setBreakpointAtLine(line),
+ resumeProgramRecordingStops(stops, false),
+ checkRecordedStops(stops, expected),
+];
+
+main([args = const <String>[]]) => runIsolateTests(
+ args,
+ tests,
+ fileName,
+ testeeConcurrent: testMain,
+ pause_on_start: true,
+ pause_on_exit: true,
+ experiments: ['enhanced-enums'],
+ );
diff --git a/pkg/vm_service/test/enhanced_enum_test.dart b/pkg/vm_service/test/enhanced_enum_test.dart
new file mode 100644
index 0000000..633caa5
--- /dev/null
+++ b/pkg/vm_service/test/enhanced_enum_test.dart
@@ -0,0 +1,296 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// SharedOptions=--enable-experiment=enhanced-enums
+
+// ignore_for_file: experiment_not_enabled
+// @dart=2.17
+
+import 'dart:developer';
+
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+class I1 {
+ int interfaceMethod1() => 0;
+ int get interfaceGetter1 => 0;
+ set interfaceSetter1(int value) {}
+}
+
+abstract class I2 {
+ int interfaceMethod2();
+ int get interfaceGetter2;
+ set interfaceSetter2(int value);
+}
+
+mixin M on Object {
+ int mixedInMethod() => 42;
+}
+
+enum E with M implements I1, I2 {
+ e1,
+ e2,
+ e3;
+
+ int interfaceMethod1() => 42;
+ int get interfaceGetter1 => 42;
+ set interfaceSetter1(int value) {}
+ int interfaceMethod2() => 42;
+ int get interfaceGetter2 => 42;
+ set interfaceSetter2(int value) {}
+
+ static int staticMethod() => 42;
+ static int get staticGetter => _staticField;
+ static set staticSetter(int x) => _staticField = x;
+ static int _staticField = 0;
+}
+
+enum F<T> {
+ f1<int>(1),
+ f2('foo'),
+ f3(<String, dynamic>{});
+
+ const F(this.value);
+
+ void debugMethod() {
+ debugger();
+ }
+
+ final T value;
+
+ String toString() => 'OVERRIDE ${value.toString()}';
+}
+
+void testMain() {
+ debugger();
+ F.f1.debugMethod();
+}
+
+Future<void> expectError(func) async {
+ bool gotException = false;
+ try {
+ await func();
+ fail('Failed to throw');
+ } on RPCError catch (e) {
+ expect(e.code, 113); // Compile time error.
+ gotException = true;
+ }
+ expect(gotException, true);
+}
+
+late final String isolateId;
+late final Isolate isolate;
+late final String rootLibraryId;
+late final Class enumECls;
+late final String enumEClsId;
+late final Class enumFCls;
+late final String enumFClsId;
+
+final tests = <IsolateTest>[
+ hasStoppedAtBreakpoint,
+ (VmService service, IsolateRef isolateRef) async {
+ // Initialization.
+ isolateId = isolateRef.id!;
+ isolate = await service.getIsolate(isolateId);
+ rootLibraryId = isolate.rootLib!.id!;
+ final rootLibrary = await service.getObject(
+ isolateId,
+ rootLibraryId,
+ ) as Library;
+
+ final enumERef = rootLibrary.classes!.firstWhere((c) => c.name == 'E');
+ enumECls = await service.getObject(isolateId, enumERef.id!) as Class;
+ enumEClsId = enumECls.id!;
+
+ final enumFRef = rootLibrary.classes!.firstWhere((c) => c.name == 'F');
+ enumFCls = await service.getObject(isolateId, enumFRef.id!) as Class;
+ enumFClsId = enumFCls.id!;
+ },
+ (VmService service, _) async {
+ // Check all functions and fields are found.
+ expect(
+ enumECls.functions!.map((f) => f.name),
+ containsAll([
+ 'e1',
+ 'e2',
+ 'e3',
+ 'values',
+ 'toString',
+ 'interfaceSetter1=',
+ 'interfaceGetter1',
+ 'interfaceSetter2=',
+ 'interfaceGetter2',
+ 'interfaceMethod1',
+ 'interfaceMethod2',
+ 'staticGetter',
+ 'staticSetter=',
+ ]),
+ );
+ expect(
+ enumECls.fields!.map((f) => f.name),
+ containsAll([
+ 'e1',
+ 'e2',
+ 'e3',
+ 'values',
+ '_staticField',
+ ]),
+ );
+ },
+ (VmService service, _) async {
+ // Ensure attempting to create an instance of an Enum fails.
+ await expectError(() => service.evaluate(isolateId, rootLibraryId, 'E()'));
+ await expectError(
+ () => service.evaluate(isolateId, rootLibraryId, 'E(10, "staticGetter")'),
+ );
+ },
+ (VmService service, _) async {
+ // Ensure we can evaluate enum values in the context of the enum Class.
+ dynamic result = await service.evaluate(isolateId, enumEClsId, 'e1');
+ expect(result, isA<InstanceRef>());
+ expect(result.classRef.name, 'E');
+ result = await service.evaluate(isolateId, result.id!, 'name');
+ expect(result.valueAsString, 'e1');
+
+ result = await service.evaluate(isolateId, enumEClsId, 'e2');
+ expect(result, isA<InstanceRef>());
+ expect(result.classRef.name, 'E');
+ result = await service.evaluate(isolateId, result.id!, 'name');
+ expect(result.valueAsString, 'e2');
+
+ result = await service.evaluate(isolateId, enumEClsId, 'e3');
+ expect(result, isA<InstanceRef>());
+ expect(result.classRef.name, 'E');
+ result = await service.evaluate(isolateId, result.id!, 'name');
+ expect(result.valueAsString, 'e3');
+ },
+ (VmService service, _) async {
+ // Ensure we can evaluate enum values in the context of the library.
+ dynamic result = await service.evaluate(isolateId, rootLibraryId, 'E.e1');
+ expect(result, isA<InstanceRef>());
+ expect(result.classRef.name, 'E');
+ result = await service.evaluate(isolateId, result.id!, 'name');
+ expect(result.valueAsString, 'e1');
+
+ result = await service.evaluate(isolateId, rootLibraryId, 'E.e2');
+ expect(result, isA<InstanceRef>());
+ expect(result.classRef.name, 'E');
+ result = await service.evaluate(isolateId, result.id!, 'name');
+ expect(result.valueAsString, 'e2');
+
+ result = await service.evaluate(isolateId, rootLibraryId, 'E.e3');
+ expect(result, isA<InstanceRef>());
+ expect(result.classRef.name, 'E');
+ result = await service.evaluate(isolateId, result.id!, 'name');
+ expect(result.valueAsString, 'e3');
+ },
+ (VmService service, _) async {
+ // Ensure we can evaluate instance getters and methods.
+ dynamic e1 = await service.evaluate(isolateId, enumEClsId, 'e1');
+ expect(e1, isA<InstanceRef>());
+ final e1Id = e1.id!;
+
+ dynamic result = await service.evaluate(isolateId, e1Id, 'interfaceGetter1');
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '42');
+
+ result = await service.evaluate(isolateId, e1Id, 'interfaceGetter2');
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '42');
+
+ result = await service.evaluate(isolateId, e1Id, 'interfaceMethod1()');
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '42');
+
+ result = await service.evaluate(isolateId, e1Id, 'interfaceMethod2()');
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '42');
+
+ result = await service.evaluate(isolateId, e1Id, 'mixedInMethod()');
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '42');
+
+ result = await service.evaluate(isolateId, e1Id, 'toString()');
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, 'E.e1');
+ },
+ (VmService service, _) async {
+ // Ensure we can evaluate static getters and methods.
+ dynamic result = await service.evaluate(isolateId, enumEClsId, 'staticGetter');
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '0');
+
+ result = await service.evaluate(isolateId, enumEClsId, 'staticMethod()');
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '42');
+ },
+ (VmService service, _) async {
+ // Ensure we can invoke instance methods.
+ dynamic e1 = await service.evaluate(isolateId, enumEClsId, 'e1');
+ expect(e1, isA<InstanceRef>());
+ final e1Id = e1.id!;
+
+ dynamic result = await service.invoke(isolateId, e1Id, 'interfaceMethod1', []);
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '42');
+
+ result = await service.invoke(isolateId, e1Id, 'interfaceMethod2', []);
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '42');
+
+ result = await service.invoke(isolateId, e1Id, 'mixedInMethod', []);
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '42');
+
+ result = await service.invoke(isolateId, e1Id, 'toString', []);
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, 'E.e1');
+ },
+ (VmService service, _) async {
+ // Ensure we can invoke static methods.
+ dynamic result = await service.evaluate(isolateId, enumEClsId, 'staticMethod()');
+ expect(result, isA<InstanceRef>());
+ expect(result.valueAsString, '42');
+ },
+ (VmService service, _) async {
+ // Ensure we can evaluate enums user defined properties.
+ dynamic result = await service.evaluate(isolateId, rootLibraryId, 'F.f1');
+ expect(result, isA<InstanceRef>());
+ expect(result.classRef.name, 'F');
+ result = await service.evaluate(isolateId, result.id!, 'value');
+ expect(result.valueAsString, '1');
+
+ result = await service.evaluate(isolateId, rootLibraryId, 'F.f2');
+ expect(result, isA<InstanceRef>());
+ expect(result.classRef.name, 'F');
+ result = await service.evaluate(isolateId, result.id!, 'value');
+ expect(result.valueAsString, 'foo');
+
+ result = await service.evaluate(isolateId, rootLibraryId, 'F.f3');
+ expect(result, isA<InstanceRef>());
+ expect(result.classRef.name, 'F');
+ result = await service.evaluate(isolateId, result.id!, 'value');
+ expect(result.kind, 'Map');
+ },
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ (VmService service, _) async {
+ dynamic result = await service.evaluateInFrame(isolateId, 0, 'T.toString()');
+ expect(result.valueAsString, 'int');
+
+ result = await service.evaluateInFrame(isolateId, 0, 'value');
+ expect(result.kind, 'Int');
+ },
+];
+
+main([args = const <String>[]]) => runIsolateTests(
+ args,
+ tests,
+ 'enhanced_enum_test.dart',
+ testeeConcurrent: testMain,
+ experiments: ['enhanced-enums'],
+ );
diff --git a/tools/VERSION b/tools/VERSION
index eeb0ced..dd3a291 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 108
+PRERELEASE 109
PRERELEASE_PATCH 0
\ No newline at end of file