private DeclaredTypeAssignment?GetIfConditionType(IfConditionSyntax syntax) { var parent = this.binder.GetParent(syntax); if (parent == null) { return(null); } var parentTypeAssignment = GetDeclaredTypeAssignment(parent); if (parentTypeAssignment == null) { return(null); } var parentType = parentTypeAssignment.Reference.Type; switch (parent) { case ResourceDeclarationSyntax _ when parentType is ResourceType resourceType && syntax.Body is ObjectSyntax resourceBody: return(TryCreateAssignment(ResolveDiscriminatedObjects(resourceType.Body.Type, resourceBody), syntax)); case ModuleDeclarationSyntax _ when parentType is ModuleType moduleType && syntax.Body is ObjectSyntax moduleBody: return(TryCreateAssignment(ResolveDiscriminatedObjects(moduleType.Body.Type, moduleBody), syntax)); default: return(null); } }
public override void VisitIfConditionSyntax(IfConditionSyntax syntax) { this.Visit(syntax.Keyword); allowedFlags = FunctionFlags.Default; this.Visit(syntax.ConditionExpression); // if-condition syntax parent is always a resource/module declaration // this means that we have to allow the functions that are only allowed // in resource bodies by our runtime (like reference() or listKeys()) // TODO: Update when conditions can be composed together with loops allowedFlags = FunctionFlags.RequiresInlining; this.Visit(syntax.Body); allowedFlags = FunctionFlags.Default; }
public override void VisitIfConditionSyntax(IfConditionSyntax syntax) { this.Visit(syntax.Keyword); this.deployTimeConstantScopeSyntax = syntax; this.Visit(syntax.ConditionExpression); if (this.errorSyntax != null) { this.AppendError(); } this.deployTimeConstantScopeSyntax = null; this.Visit(syntax.Body); }
public override void VisitIfConditionSyntax(IfConditionSyntax syntax) => this.BuildWithSpread(() => base.VisitIfConditionSyntax(syntax));
protected override SyntaxBase ReplaceResourceDeclarationSyntax(ResourceDeclarationSyntax syntax) { if (syntax.TryGetBody() is not ObjectSyntax resourceBody || resourceBody.SafeGetPropertyByName("name") is not ObjectPropertySyntax resourceNameProp || resourceNameProp.Value is not StringSyntax resourceName) { return(syntax); } if (semanticModel.GetSymbolInfo(syntax) is not ResourceSymbol resourceSymbol || resourceSymbol.Type is not ResourceType resourceType) { return(syntax); } if (resourceType.TypeReference.Types.Length < 2) { // we're only looking for child resources here return(syntax); } foreach (var otherResource in semanticModel.AllResources) { var otherResourceSymbol = otherResource.Symbol; if (otherResourceSymbol.Type is not ResourceType otherResourceType || otherResourceType.TypeReference.Types.Length != resourceType.TypeReference.Types.Length - 1 || !resourceType.TypeReference.TypesString.StartsWith($"{otherResourceType.TypeReference.TypesString}/", StringComparison.OrdinalIgnoreCase)) { continue; } // The other resource is a parent type to this one. check if we can refactor the name. if (otherResourceSymbol.DeclaringResource.TryGetBody() is not ObjectSyntax otherResourceBody || otherResourceBody.SafeGetPropertyByName("name") is not ObjectPropertySyntax otherResourceNameProp) { continue; } if (TryGetReplacementChildName(resourceName, otherResourceNameProp.Value, otherResourceSymbol) is not { } newName) { continue; } var replacementNameProp = new ObjectPropertySyntax(resourceNameProp.Key, resourceNameProp.Colon, newName); var parentProp = new ObjectPropertySyntax( SyntaxFactory.CreateIdentifier(LanguageConstants.ResourceParentPropertyName), SyntaxFactory.ColonToken, SyntaxFactory.CreateVariableAccess(otherResourceSymbol.Name)); var replacementBody = new ObjectSyntax( resourceBody.OpenBrace, // parent prop comes first! parentProp.AsEnumerable().Concat(resourceBody.Children.Replace(resourceNameProp, replacementNameProp)), resourceBody.CloseBrace); // at the top we just checked if there is a legitimate body // but to do the replacement correctly we may need to wrap it inside an IfConditionSyntax SyntaxBase replacementValue = syntax.Value switch { ObjectSyntax => replacementBody, IfConditionSyntax ifCondition => new IfConditionSyntax(ifCondition.Keyword, ifCondition.ConditionExpression, replacementBody), // should not be possible _ => throw new NotImplementedException($"Unexpected resource value type '{syntax.Value.GetType().Name}'.") }; return(new ResourceDeclarationSyntax( syntax.LeadingNodes, syntax.Keyword, syntax.Name, syntax.Type, syntax.ExistingKeyword, syntax.Assignment, replacementValue)); } return(syntax); }
public override void VisitIfConditionSyntax(IfConditionSyntax syntax) => AssignTypeWithDiagnostics(syntax, diagnostics => { diagnostics.WriteMultiple(this.ValidateIfCondition(syntax)); return(this.typeManager.GetTypeInfo(syntax.Body)); });