protected override SyntaxBase ReplaceObjectSyntax(ObjectSyntax syntax) { var declaredType = semanticModel.GetDeclaredType(syntax); if (declaredType is not ObjectType objectType) { return(base.ReplaceObjectSyntax(syntax)); } var newChildren = new List <SyntaxBase>(); foreach (var child in syntax.Children) { if (child is ObjectPropertySyntax objectProperty && objectProperty.TryGetKeyText() is string propertyKey && !objectType.Properties.ContainsKey(propertyKey)) { var insensitivePropertyKey = objectType.Properties.Keys.FirstOrDefault(x => StringComparer.OrdinalIgnoreCase.Equals(x, propertyKey)); if (insensitivePropertyKey != null) { SyntaxBase newKeySyntax; if (Regex.IsMatch(insensitivePropertyKey, "^[a-zA-Z][a-zA-Z0-9_]*$")) { newKeySyntax = new IdentifierSyntax(new Token(TokenType.Identifier, new TextSpan(0, 0), insensitivePropertyKey, Enumerable.Empty <SyntaxTrivia>(), Enumerable.Empty <SyntaxTrivia>())); } else { var stringToken = new Token(TokenType.StringComplete, new TextSpan(0, 0), StringUtils.EscapeBicepString(insensitivePropertyKey), Enumerable.Empty <SyntaxTrivia>(), Enumerable.Empty <SyntaxTrivia>()); newKeySyntax = new StringSyntax(stringToken.AsEnumerable(), Enumerable.Empty <SyntaxBase>(), insensitivePropertyKey.AsEnumerable()); } newChildren.Add(new ObjectPropertySyntax( newKeySyntax, objectProperty.Colon, Rewrite(objectProperty.Value))); continue; } } newChildren.Add(Rewrite(child)); } if (Enumerable.SequenceEqual(newChildren, syntax.Children)) { return(base.ReplaceObjectSyntax(syntax)); } return(new ObjectSyntax( syntax.OpenBrace, newChildren, syntax.CloseBrace)); }
private IEnumerable <CompletionItem> GetObjectPropertyCompletions(SemanticModel model, BicepCompletionContext context) { if (context.Kind.HasFlag(BicepCompletionContextKind.PropertyName) == false || context.Object == null) { return(Enumerable.Empty <CompletionItem>()); } // in order to provide completions for property names, // we need to establish the type of the object first var type = model.GetTypeInfo(context.Object); var declaredType = model.GetDeclaredType(context.Object); if (declaredType == null) { return(Enumerable.Empty <CompletionItem>()); } var specifiedPropertyNames = context.Object.ToKnownPropertyNames(); // exclude read-only properties as they can't be set // exclude properties whose name has been specified in the object already return(GetProperties(declaredType) .Where(p => p.Flags.HasFlag(TypePropertyFlags.ReadOnly) == false && specifiedPropertyNames.Contains(p.Name) == false) .Select(CreatePropertyCompletion)); }
protected override SyntaxBase ReplaceObjectSyntax(ObjectSyntax syntax) { var declaredType = semanticModel.GetDeclaredType(syntax); if (declaredType is not ObjectType objectType) { return(base.ReplaceObjectSyntax(syntax)); } var newChildren = new List <SyntaxBase>(); foreach (var child in syntax.Children) { if (child is ObjectPropertySyntax objectProperty && objectProperty.TryGetKeyText() is string propertyKey && objectType.Properties.TryGetValue(propertyKey) is {} propertyValue&& propertyValue.Flags.HasFlag(TypePropertyFlags.ReadOnly)) { continue; } if (child is ObjectPropertySyntax nullProperty && nullProperty.Value is NullLiteralSyntax) { // skip null values continue; } if (child is Token { Type: TokenType.NewLine } &&
private IEnumerable <CompletionItem> GetTargetScopeCompletions(SemanticModel model, BicepCompletionContext context) { return(context.Kind.HasFlag(BicepCompletionContextKind.TargetScope) && context.TargetScope is {} targetScope ? GetValueCompletionsForType(model.GetDeclaredType(targetScope), context.ReplacementRange) : Enumerable.Empty <CompletionItem>()); }