Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
 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);
        }
Exemplo n.º 4
0
 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);
        }
Exemplo n.º 6
0
 public override void VisitIfConditionSyntax(IfConditionSyntax syntax)
 => AssignTypeWithDiagnostics(syntax, diagnostics =>
 {
     diagnostics.WriteMultiple(this.ValidateIfCondition(syntax));
     return(this.typeManager.GetTypeInfo(syntax.Body));
 });