private boolean setParsedPropertyValueHelper()

in flutter-idea/src/io/flutter/editor/PropertyEditorPanel.java [657:771]


  private boolean setParsedPropertyValueHelper(String propertyName, FlutterWidgetPropertyValue value) {
    // TODO(jacobr): also do simple tracking of how the previous expression maps to the current expression to avoid spurious edits.

    // Treat an empty expression and empty value objects as omitted values
    // indicating the property should be removed.
    final FlutterWidgetPropertyValue emptyValue = new FlutterWidgetPropertyValue(null, null, null, null, null, null);

    final FlutterWidgetProperty property = propertyMap.get(propertyName);
    if (property == null) {
      // UI is in the process of updating. Skip this action.
      return false;
    }

    if (property.getExpression() != null && property.getExpression().equals(value.getExpression())) {
      return false;
    }

    if (value != null && Objects.equals(value.getExpression(), "") || emptyValue.equals(value)) {
      // Normalize empty expressions to simplify calling this api.
      value = null;
    }

    final String lastExpression = currentExpressionMap.get(propertyName);
    if (lastExpression != null && value != null && lastExpression.equals(value.getExpression())) {
      return false;
    }
    currentExpressionMap.put(propertyName, value != null ? value.getExpression() : null);

    final FlutterWidgetPropertyEditor editor = property.getEditor();
    if (editor != null && value != null && value.getExpression() != null) {
      final String expression = value.getExpression();
      // Normalize expressions as primitive values.
      final String kind = editor.getKind();
      switch (kind) {
        case FlutterWidgetPropertyEditorKind.BOOL: {
          if (expression.equals("true")) {
            value = new FlutterWidgetPropertyValue(true, null, null, null, null, null);
          }
          else if (expression.equals("false")) {
            value = new FlutterWidgetPropertyValue(false, null, null, null, null, null);
          }
        }
        break;
        case FlutterWidgetPropertyEditorKind.STRING: {
          // TODO(jacobr): there might be non-string literal cases that match this patterned.
          if (expression.length() >= 2 && (
            (expression.startsWith("'") && expression.endsWith("'")) ||
            (expression.startsWith("\"") && expression.endsWith("\"")))) {
            value = new FlutterWidgetPropertyValue(null, null, null, expression.substring(1, expression.length() - 1), null, null);
          }
        }
        break;
        case FlutterWidgetPropertyEditorKind.DOUBLE: {
          try {
            final double doubleValue = Double.parseDouble(expression);
            if (((double)((int)doubleValue)) == doubleValue) {
              // Express doubles that can be expressed as ints as ints.
              value = new FlutterWidgetPropertyValue(null, null, (int)doubleValue, null, null, null);
            }
            else {
              value = new FlutterWidgetPropertyValue(null, doubleValue, null, null, null, null);
            }
          }
          catch (NumberFormatException e) {
            // Don't convert value.
          }
        }
        break;
        case FlutterWidgetPropertyEditorKind.INT: {
          try {
            final int intValue = Integer.parseInt(expression);
            value = new FlutterWidgetPropertyValue(null, null, intValue, null, null, null);
          }
          catch (NumberFormatException e) {
            // Don't convert value.
          }
        }
        break;
      }
    }
    if (Objects.equals(property.getValue(), value)) {
      // Short circuit as nothing changed.
      return false;
    }

    final SourceChange change;
    try {
      change = flutterDartAnalysisService.setWidgetPropertyValue(property.getId(), value);
    }
    catch (Exception e) {
      if (value != null && value.getExpression() != null) {
        FlutterMessages.showInfo("Invalid property value", value.getExpression(), project);
      }
      else {
        FlutterMessages.showError("Unable to set propery value", e.getMessage(), project);
      }
      return false;
    }

    if (change != null && change.getEdits() != null && !change.getEdits().isEmpty()) {
      // TODO(jacobr): does running a write action make sense here? We are
      // already on the UI thread.
      ApplicationManager.getApplication().runWriteAction(() -> {
        try {
          AssistUtils.applySourceChange(project, change, false);
          hotReload();
        }
        catch (DartSourceEditException exception) {
          FlutterMessages.showInfo("Failed to apply code change", exception.getMessage(), project);
        }
      });
      return true;
    }
    return false;
  }