2.2.3.7 release notes

 2.2.3.7

  • Issue 2197 - Made the safe navigation operator even safer by flagging usages of that operator in expressions which can, by definition, evaluate to a null value in contexts which require a non-null value, e.g., control flow conditions, logical/arithmetic/relational expressions, DML statements, array bounds, thrown exceptions, etc. These types of issues are reported as warnings with a quick fix to replace the safe navigation operator (?.) with the standard navigation operator (.). Note that in the process I also noticed that usages of the safe navigation operator in unary pre- and post- increment and decrement expressions should result in an error just as with a usage of the safe navigation operator on the left-hand side of an assignment expression.
  • Implemented a number of quality-of-life improvements in the Apex language editor:
    • Improved smart completion in invocation argument lists such that after a smart completion is accepted for an argument expression, the caret is automatically moved to provide the next argument expression if the known invoked method/constructor signatures require additional arguments or overloaded signatures support additional arguments and there is already a comma after the current argument. Comma delimiters are automatically added or skipped as appropriate, and once the signature is complete, the caret is moved out of the invocation arguments altogether. This makes filling out invocation argument lists very quick and accurate when performed via smart completion. As a reminder, smart completion is triggered by Ctrl+Shift+Space vs. Ctrl+Space for basic completion. For more details, see this demo video.
    • Significant improvements for constructor completions including:
      • All available signatures are listed including default no-arg constructors.
      • Icons are now based on the containing class instead of using the method icon.
      • SObject constructor parameters are displayed as (...).
      • Upon accepting a completion for an SObject constructor, the caret is now placed within the invocation argument list parentheses.
    • When accepting a completion for a method with a void return type in what appears to be an expression statement, a statement terminator (;) is automatically added. If the void method has parameters, the caret is automatically placed between the argument list parentheses as before; if not, the caret is automatically placed at the end of the new expression statement.
    • Significant improvements in the order of offered Apex code completions. Completions are now ordered as follows with each check occurring first in a case-sensitive manner and then in a case-insensitive manner:
      1. Exact matches against the current identifier name at the caret.
      2. Exact matches against the inferred identifier name at the caret, e.g., the formal parameter name in the method or constructor signature corresponding to the current invocation argument.
      3. Exact matches against variants of the inferred identifier name at the caret, e.g., for an inferred name of activeAccountList, the variants would be accountList and list.
      4. Exact matches against variants of the expected data type at the caret, e.g., for an expected data type of MyApplicationController, the variants would be myApplicationControllerapplicationController, and controller.
      5. Starts-with matches against the existing prefix when completion is triggered after the start of an existing name.
      6. All other candidate completions.
      Completions in each category should be ordered by relative proximity to the caret based on nested lexical scope, e.g., a local variable or parameter with the same name as a field would be ordered with the local variable/parameter before the field.
    • Addressed a number of contextual type inference gaps. This helps to improve smart completion, variable name suggestions, etc., based on the expected data type at the point of insertion. Type inference now works properly for conditions in flow control statements (always Boolean), collections in enhanced for loops (based on the type of the loop variable if present; otherwise any iterable type), and the left-hand side of a relational expression based on the right-hand side type (in addition to the opposite that was already supported).
    • Fixed an issue with type inference for the bitwise complement operator (~) which would previously evaluate to Boolean but now evaluates properly to the operand data type.
    • Extended the text range for errors reported by the Illegal Assignment code inspection to include the entire statement for expressions in an expression statement. This ensures that the quick fixes can be triggered even after the statement terminator (;), e.g., to add a cast operator in the following scenario:

      Account acct = /*needs a cast here*/standardController.getSubject();<caretIsHere>

  • Fixed an issue with the Apex Modifier and Annotation Agreement and Control Flow Analysis code inspections where fields denoted with @InvocableVariable or @JsonAccess(Deserializable='always|sameNamespace|samePackage') would not properly report invalid usages of the final modifier.
  • Fixed an issue with the Apex Modifier and Annotation Agreement code inspection where declarations without an explicit visibility modifier would not be properly checked as having one of the required visibilities based on other modifiers and/or annotations.
  • Quite a few other fixes and improvements including one overall performance optimization that will likely yield the most benefit in larger Apex source files.