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;
}