Tentative implementation of dynamic vm_type CA and reconcile

It is functional but still need to address caching issues
This commit is contained in:
Kris De Volder
2017-07-19 08:59:56 -07:00
parent cecd98f7a5
commit 35a558be37
7 changed files with 105 additions and 20 deletions

View File

@@ -146,7 +146,7 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
YAtomicType t_vm_extension = f.yatomic("VMExtension"); //TODO: resolve dynamically from 'cloud config' ? https://www.pivotaltracker.com/story/show/148703877
t_vm_extension.parseWith(ValueParsers.NE_STRING);
YAtomicType t_vm_type = f.yatomic("VMType"); //TODO: resolve dynamically from 'cloud config' ? https://www.pivotaltracker.com/story/show/148686169
YAtomicType t_vm_type = f.yenumFromDynamicValues("VMType", (dc) -> cloudConfigProvider.getCloudConfig(dc).getVMTypes());
t_vm_type.parseWith(ValueParsers.NE_STRING);
YAtomicType t_az = f.yatomic("AvailabilityZone"); //TODO: resolve dynamically from 'cloud config': https://www.pivotaltracker.com/story/show/148704481

View File

@@ -14,7 +14,6 @@ import static org.springframework.ide.vscode.languageserver.testharness.Editor.P
import org.junit.Before;
import org.junit.Test;
import org.springframework.ide.vscode.bosh.BoshLanguageServer;
import org.springframework.ide.vscode.commons.util.text.LanguageId;
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
import org.springframework.ide.vscode.languageserver.testharness.Editor;
@@ -828,4 +827,19 @@ public class BoshEditorTest {
);
}
@Test public void contentAssistVMtype() throws Exception {
Editor editor = harness.newEditor(
"name: foo\n" +
"instance_groups: \n" +
"- name: some-server\n" +
" stemcell: windoze\n" +
" vm_type: <*>"
);
editor.assertContextualCompletions(
"<*>"
, // ==>
"default<*>",
"large<*>"
);
}
}

View File

@@ -0,0 +1,59 @@
eclipse.preferences.version=1
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
sp_cleanup.add_default_serial_version_id=true
sp_cleanup.add_generated_serial_version_id=false
sp_cleanup.add_missing_annotations=true
sp_cleanup.add_missing_deprecated_annotations=true
sp_cleanup.add_missing_methods=false
sp_cleanup.add_missing_nls_tags=false
sp_cleanup.add_missing_override_annotations=true
sp_cleanup.add_missing_override_annotations_interface_methods=true
sp_cleanup.add_serial_version_id=false
sp_cleanup.always_use_blocks=true
sp_cleanup.always_use_parentheses_in_expressions=false
sp_cleanup.always_use_this_for_non_static_field_access=false
sp_cleanup.always_use_this_for_non_static_method_access=false
sp_cleanup.convert_functional_interfaces=false
sp_cleanup.convert_to_enhanced_for_loop=false
sp_cleanup.correct_indentation=false
sp_cleanup.format_source_code=false
sp_cleanup.format_source_code_changes_only=false
sp_cleanup.insert_inferred_type_arguments=false
sp_cleanup.make_local_variable_final=true
sp_cleanup.make_parameters_final=false
sp_cleanup.make_private_fields_final=true
sp_cleanup.make_type_abstract_if_missing_method=false
sp_cleanup.make_variable_declarations_final=false
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
sp_cleanup.on_save_use_additional_actions=true
sp_cleanup.organize_imports=false
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
sp_cleanup.remove_redundant_type_arguments=false
sp_cleanup.remove_trailing_whitespaces=true
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
sp_cleanup.remove_unnecessary_casts=true
sp_cleanup.remove_unnecessary_nls_tags=false
sp_cleanup.remove_unused_imports=false
sp_cleanup.remove_unused_local_variables=false
sp_cleanup.remove_unused_private_fields=true
sp_cleanup.remove_unused_private_members=false
sp_cleanup.remove_unused_private_methods=true
sp_cleanup.remove_unused_private_types=true
sp_cleanup.sort_members=false
sp_cleanup.sort_members_all=false
sp_cleanup.use_anonymous_class_creation=false
sp_cleanup.use_blocks=false
sp_cleanup.use_blocks_only_for_return_and_throw=false
sp_cleanup.use_lambda=true
sp_cleanup.use_parentheses_in_expressions=false
sp_cleanup.use_this_for_non_static_field_access=false
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
sp_cleanup.use_this_for_non_static_method_access=false
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true

View File

@@ -194,8 +194,7 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
SchemaContextAware<ValueParser> parserProvider = typeUtil.getValueParser(type);
if (parserProvider!=null) {
delayedConstraints.add(() -> {
ValueParser parser = parserProvider.withContext(schemaContext);
if (parser!=null) {
parserProvider.safeWithContext(schemaContext).ifPresent(parser -> {
try {
String value = NodeUtil.asScalar(node);
if (value!=null) {
@@ -207,7 +206,7 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
String msg = getMessage(e);
valueParseError(type, region, msg, problemType, getValueReplacement(e));
}
}
});
});
}
} else {

View File

@@ -10,6 +10,8 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.yaml.schema;
import java.util.Optional;
/**
* Interface that can be implemented by something producing another
* component (of some type `T`) where the returned component needs to
@@ -19,7 +21,18 @@ package org.springframework.ide.vscode.commons.yaml.schema;
*/
@FunctionalInterface
public interface SchemaContextAware<T> {
T withContext(DynamicSchemaContext dc);
T withContext(DynamicSchemaContext dc) throws Exception;
/**
* Like `withContext' method, but swallows exceptions silently.
*/
default Optional<T> safeWithContext(DynamicSchemaContext dc) {
try {
return Optional.ofNullable(withContext(dc));
} catch (Exception e) {
return Optional.empty();
}
}
/**
* Convert a plain value into a {@link SchemaContextAware} that ignores the context and simply returns the value.

View File

@@ -157,7 +157,7 @@ public class YTypeFactory {
* YTypeFactory
*/
public final YTypeUtil TYPE_UTIL = new YTypeUtil() {
@Override
public boolean isSequencable(YType type) {
return ((AbstractType)type).isSequenceable();
@@ -257,6 +257,8 @@ public class YTypeFactory {
private List<YValueHint> hints = new ArrayList<>();
private Map<String, YTypedProperty> cachedPropertyMap;
private SchemaContextAware<Callable<Collection<YValueHint>>> hintProvider;
//TODO: SchemaContextAware now allows throwing exceptions so should be able to simplify the above to SchemaContextAware<Collection<YValueHint>>
private List<Constraint> constraints = new ArrayList<>(2);
private ISubCompletionEngine customContentAssistant = null;
@@ -267,7 +269,7 @@ public class YTypeFactory {
public ISubCompletionEngine getCustomContentAssistant() {
return customContentAssistant;
}
public AbstractType setCustomContentAssistant(ISubCompletionEngine customContentAssistant) {
this.customContentAssistant = customContentAssistant;
return this;
@@ -295,6 +297,7 @@ public class YTypeFactory {
}
public AbstractType addHintProvider(SchemaContextAware<Callable<Collection<YValueHint>>> hintProvider) {
//TODO: SchemaContextAware now allows throwing exceptions so should be able to simplify the above to SchemaContextAware<Collection<YValueHint>>
this.hintProvider = hintProvider;
return this;
}
@@ -448,10 +451,7 @@ public class YTypeFactory {
@Override
public YType inferMoreSpecificType(DynamicSchemaContext dc) {
if (dc!=null) {
YType inferred = typeGuesser.withContext(dc);
if (inferred!=null) {
return inferred;
}
return typeGuesser.safeWithContext(dc).orElse(this);
}
return this;
}
@@ -797,7 +797,7 @@ public class YTypeFactory {
this.isDeprecated = deprecationMessage!=null;
this.deprecationMessage = deprecationMessage;
}
@Override
public String getDeprecationMessage() {
return this.deprecationMessage;
@@ -808,7 +808,7 @@ public class YTypeFactory {
return this.isDeprecated;
}
public YTypedPropertyImpl isPrimary(boolean primary) {
this.isPrimary = primary;
this.isRequired = primary;
@@ -820,7 +820,7 @@ public class YTypeFactory {
this.isRequired = required;
return this;
}
@Override
public boolean isPrimary() {
return isPrimary;
@@ -842,7 +842,7 @@ public class YTypeFactory {
public YTypedPropertyImpl yprop(String name, YType type) {
return new YTypedPropertyImpl(name, type);
}
public YTypedPropertyImpl yprop(YTypedProperty prop) {
return ((YTypedPropertyImpl)prop).copy();
}
@@ -863,16 +863,16 @@ public class YTypeFactory {
}
public YAtomicType yenumFromDynamicValues(String name, SchemaContextAware<Collection<String>> values) {
return yenumFromHints(name,
return yenumFromHints(name,
//Error message formatter:
(parseString, validValues) -> "'"+parseString+"' is an unknown '"+name+"'. Valid values are: "+validValues,
//Hints provider:
(dc) ->
(dc) ->
hints(values.withContext(dc)
)
);
}
public EnumTypeBuilder yenumBuilder(String name, String... values) {
return new EnumTypeBuilder(name, values);
}

View File

@@ -141,7 +141,7 @@ public class Constraints {
@Deprecated
public static Constraint schemaContextAware(SchemaContextAware<Constraint> dispatcher) {
return (DynamicSchemaContext dc, Node parent, Node node, YType type, IProblemCollector problems) -> {
dispatcher.withContext(dc).verify(dc, parent, node, type, problems);
dispatcher.safeWithContext(dc).ifPresent((constraint) -> constraint.verify(dc, parent, node, type, problems));
};
}