Exemple #1
0
 override public void Compile(CompilationContext context)
 {
     CompilationHelper.CheckIsValue(itemType);
     array.Compile(context);
     context.Emit(OpCodes.Ldc_I4, index);
     context.Emit(OpCodes.Ldelema, itemType);
 }
        private void RunWithDiagnosticAnnotations(string bicepText, Func <IDiagnostic, bool> filterFunc, OnCompileErrors onCompileErrors, Action <IEnumerable <IDiagnostic> > assertAction)
        {
            using (AssertionScope scope = new AssertionScope())
            {
                scope.AddReportable("bicep code", bicepText);

                var result = CompilationHelper.Compile(bicepText);
                result.Should().NotHaveDiagnosticsWithCodes(new[] { LinterAnalyzer.LinterRuleInternalError }, "There should never be linter LinterRuleInternalError errors");

                if (onCompileErrors == OnCompileErrors.Fail)
                {
                    var compileErrors = result.Diagnostics.Where(d => d.Level == DiagnosticLevel.Error);
                    DiagnosticAssertions.DoWithDiagnosticAnnotations(
                        result.Compilation.SourceFileGrouping.EntryPoint,
                        compileErrors,
                        diags => diags.Should().HaveCount(0));
                }

                IDiagnostic[] diagnosticsMatchingCode = result.Diagnostics.Where(filterFunc).ToArray();
                DiagnosticAssertions.DoWithDiagnosticAnnotations(
                    result.Compilation.SourceFileGrouping.EntryPoint,
                    result.Diagnostics.Where(filterFunc),
                    assertAction);
            }
        }
Exemple #3
0
        [Test] // improve: either?
        public void Problem1_AddAllNaturalNumbersBelow1000_ThatAreMultiplesOf3Or5()
        {
            var code   = "(1..1000).Where(x => (x mod 3 == 0) or (x mod 5 == 0)).Sum()";
            var result = CompilationHelper.CompileAndEvaluate(code);

            Assert.AreEqual(new Integer(233168), result);
        }
Exemple #4
0
 /// <summary>
 /// </summary>
 /// <param name="context">The context.</param>
 public override void Compile(CompilationContext context)
 {
     CompilationHelper.CheckIsValue(ItemType);
     Array.Compile(context);
     context.Emit(OpCodes.Ldc_I4, Index);
     context.Emit(OpCodes.Ldelema, ItemType);
 }
        public void Emitter_should_generate_correct_extension_scope_property_and_correct_dependsOn()
        {
            var(json, diags) = CompilationHelper.Compile(@"
resource resourceA 'My.Rp/myResource@2020-01-01' = {
  name: 'resourceA'
}

resource resourceB 'My.Rp/myResource@2020-01-01' = {
  scope: resourceA
  name: 'resourceB'
}

resource resourceC 'My.Rp/myResource@2020-01-01' = {
  scope: resourceB
  name: 'resourceC'
}");

            json.Should().NotBeNull();
            var template = JObject.Parse(json !);

            using (new AssertionScope())
            {
                template.SelectToken("$.resources[?(@.name == 'resourceB')].scope") !.ToString().Should().Be("[format('My.Rp/myResource/{0}', 'resourceA')]");
                template.SelectToken("$.resources[?(@.name == 'resourceB')].dependsOn[0]") !.ToString().Should().Be("[resourceId('My.Rp/myResource', 'resourceA')]");

                template.SelectToken("$.resources[?(@.name == 'resourceC')].scope") !.ToString().Should().Be("[extensionResourceId(format('My.Rp/myResource/{0}', 'resourceA'), 'My.Rp/myResource', 'resourceB')]");
                template.SelectToken("$.resources[?(@.name == 'resourceC')].dependsOn[0]") !.ToString().Should().Be("[extensionResourceId(format('My.Rp/myResource/{0}', 'resourceA'), 'My.Rp/myResource', 'resourceB')]");
            }
        }
        public void List_wildcard_function_on_resource_references()
        {
            var result = CompilationHelper.Compile(@"
resource stg 'Microsoft.Storage/storageAccounts@2019-06-01' = {
  name: 'testacc'
  location: 'West US'
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}

#disable-next-line outputs-should-not-contain-secrets
output pkStandard string = listKeys(stg.id, stg.apiVersion).keys[0].value
#disable-next-line outputs-should-not-contain-secrets
output pkMethod string = stg.listKeys().keys[0].value
#disable-next-line outputs-should-not-contain-secrets
output pkMethodVersionOverride string = stg.listKeys('2021-01-01').keys[0].value
#disable-next-line outputs-should-not-contain-secrets
output pkMethodPayload string = stg.listKeys(stg.apiVersion, {
  key1: 'val1'
})
");

            result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics();
            result.Template.Should().HaveValueAtPath("$.outputs['pkStandard'].value", "[listKeys(resourceId('Microsoft.Storage/storageAccounts', 'testacc'), '2019-06-01').keys[0].value]");
            result.Template.Should().HaveValueAtPath("$.outputs['pkMethod'].value", "[listKeys(resourceId('Microsoft.Storage/storageAccounts', 'testacc'), '2019-06-01').keys[0].value]");
            result.Template.Should().HaveValueAtPath("$.outputs['pkMethodVersionOverride'].value", "[listKeys(resourceId('Microsoft.Storage/storageAccounts', 'testacc'), '2021-01-01').keys[0].value]");
            result.Template.Should().HaveValueAtPath("$.outputs['pkMethodPayload'].value", "[listKeys(resourceId('Microsoft.Storage/storageAccounts', 'testacc'), '2019-06-01', createObject('key1', 'val1'))]");
        }
        public void List_wildcard_function_on_cross_scope_resource_references()
        {
            var result = CompilationHelper.Compile(@"
resource stg 'Microsoft.Storage/storageAccounts@2019-06-01' existing = {
  scope: resourceGroup('other')
  name: 'testacc'
}

#disable-next-line outputs-should-not-contain-secrets
output pkStandard string = listKeys(stg.id, stg.apiVersion).keys[0].value
#disable-next-line outputs-should-not-contain-secrets
output pkMethod string = stg.listKeys().keys[0].value
#disable-next-line outputs-should-not-contain-secrets
output pkMethodVersionOverride string = stg.listKeys('2021-01-01').keys[0].value
#disable-next-line outputs-should-not-contain-secrets
output pkMethodPayload string = stg.listKeys(stg.apiVersion, {
  key1: 'val1'
})
");

            result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics();
            result.Template.Should().HaveValueAtPath("$.outputs['pkStandard'].value", "[listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, 'other'), 'Microsoft.Storage/storageAccounts', 'testacc'), '2019-06-01').keys[0].value]");
            result.Template.Should().HaveValueAtPath("$.outputs['pkMethod'].value", "[listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, 'other'), 'Microsoft.Storage/storageAccounts', 'testacc'), '2019-06-01').keys[0].value]");
            result.Template.Should().HaveValueAtPath("$.outputs['pkMethodVersionOverride'].value", "[listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, 'other'), 'Microsoft.Storage/storageAccounts', 'testacc'), '2021-01-01').keys[0].value]");
            result.Template.Should().HaveValueAtPath("$.outputs['pkMethodPayload'].value", "[listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, 'other'), 'Microsoft.Storage/storageAccounts', 'testacc'), '2019-06-01', createObject('key1', 'val1'))]");
        }
 public void Compile(CompilationContext context)
 {
     targetObject.Compile(context);
     value.Compile(context);
     CompilationHelper.PrepareValueOnStack(context, fieldInfo.FieldType, value.itemType);
     context.Emit(OpCodes.Stfld, fieldInfo);
 }
Exemple #9
0
        private void ExpectDiagnosticWithFixedText(string text, string expectedText)
        {
            var result = CompilationHelper.Compile(text);

            result.Diagnostics.Should().HaveCount(1);

            FixableDiagnostic diagnostic = (FixableDiagnostic)result.Diagnostics.Single();

            diagnostic.Code.Should().Be("BCP035");
            diagnostic.Fixes.Should().HaveCount(1);

            var fix = diagnostic.Fixes.Single();

            fix.Replacements.Should().HaveCount(1);

            var replacement = fix.Replacements.Single();

            var actualText = text.Remove(replacement.Span.Position, replacement.Span.Length);

            actualText = actualText.Insert(replacement.Span.Position, replacement.Text);

            // Normalize line endings
            expectedText = expectedText.Replace("\r\n", "\n").Replace("\n", Environment.NewLine);
            actualText   = actualText.Replace("\r\n", "\n").Replace("\n", Environment.NewLine);

            actualText.Should().Be(expectedText);
        }
Exemple #10
0
        public void BigInteger()
        {
            const string bigIntegerString = "1000000000000000000000000000000000000000";
            var          value            = CompilationHelper.CompileAndEvaluate(bigIntegerString);

            Assert.AreEqual(Framework.Integer.Parse(bigIntegerString), value);
        }
        public void Execute(SourceGeneratorContext context)
        {
            context.AddCompiledOnMetadataAttribute();

            var compilation = context.Compilation;
            var types       = CompilationHelper.GetAllTypes(context.Compilation.Assembly);

            using (var stringWriter = new StringWriter())
                using (var indentedTextWriter = new IndentedTextWriter(stringWriter, "    "))
                {
                    var defaultToStringGenerator = new DefaultToStringGenerator(context);
                    foreach (var type in types)
                    {
                        if (DefaultToStringGenerator.ShouldUseGenerator(type))
                        {
                            defaultToStringGenerator.WriteType(type, indentedTextWriter);
                        }
                    }

                    indentedTextWriter.Flush();
                    stringWriter.Flush();

                    var sourceText = SourceText.From(stringWriter.ToString(), Encoding.UTF8);
                    var hintName   = $"AutoToString_{compilation.Assembly.Name}.g.cs";

                    context.AddSource(hintName, sourceText);
                }
        }
Exemple #12
0
        public void If_ResLocationIs_AnyOtherStringLiteral_ShouldFail_AndOfferToCreateNewParameter()
        {
            var result = CompilationHelper.Compile(@"
                resource appInsightsComponents 'Microsoft.Insights/components@2020-02-02-preview' = {
                  name: 'name'
                  location: 'non-global'
                  kind: 'web'
                  properties: {
                    Application_Type: 'web'
                  }
                }"
                                                   );

            CodeFix x = result.Diagnostics.First().Should().BeAssignableTo <IFixable>()
                        .Which.Fixes.Single();

            x.Should().BeEquivalentTo(
                new
            {
                Description  = "Create new parameter 'location' with default value 'non-global'",
                Replacements = new[] {
                    // Replacement 1: change 'non-global' to 'location'
                    new { Text = "location" },
                    // Replacement 1: add new location param
                    new { Text = "@description('Specifies the location for resources.')\nparam location string = 'non-global'\n\n" }
                }
            });
        }
Exemple #13
0
        public void If_NameLocationAlreadyInUse_ShouldChooseAnotherNameForFix()
        {
            var result = CompilationHelper.Compile(@"
                var location = 'fee fie'
                param location2 string
                resource location3 'Microsoft.Insights/components@2020-02-02-preview' = {
                  name: 'name'
                  location: 'non-global'
                  kind: 'web'
                  properties: {
                    Application_Type: 'web'
                  }
                }
                output location4 string = '${location}${location2}'
                ");

            CodeFix x = result.Diagnostics.First().Should().BeAssignableTo <IFixable>()
                        .Which.Fixes.Single();

            x.Should().BeEquivalentTo(
                new
            {
                Description  = "Create new parameter 'location5' with default value 'non-global'",
                Replacements = new[] {
                    // Replacement 1: change 'non-global' to 'location5'
                    new { Text = "location5" },
                    // Replacement 1: add new location param
                    new { Text = "@description('Specifies the location for resources.')\nparam location5 string = 'non-global'\n\n" }
                }
            });
        }
        public void Casing_issues_are_corrected()
        {
            var bicepFile = @"
resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
  properties: {
    lowerCaseProp: 'abc'
    camelcaseprop: 'def'
    'lowerCaseQuoted=+.Prop': 'ghi'
    'camelcasequoted=+.prop': 'jkl'
    lowerCaseEnumProp: 'MyEnum'
    pascalCaseEnumProp: 'myenum'
    lowerCaseEnumUnionProp: 'MyEnum'
    pascalCaseEnumUnionProp: 'myenum'
  }
}

output myObj object = {
  lowerCaseProp: resA.properties.lowerCaseProp
  camelcaseprop: resA.properties.camelcaseprop
}
";

            var typeDefinition = ResourceTypeProviderHelper.CreateCustomResourceType("My.Rp/resA", "2020-01-01", TypeSymbolValidationFlags.WarnOnTypeMismatch,
                                                                                     new TypeProperty("lowercaseprop", LanguageConstants.String),
                                                                                     new TypeProperty("camelCaseProp", LanguageConstants.String),
                                                                                     new TypeProperty("lowercasequoted=+.prop", LanguageConstants.String),
                                                                                     new TypeProperty("camelCaseQuoted=+.Prop", LanguageConstants.String),
                                                                                     new TypeProperty("lowerCaseEnumProp", new StringLiteralType("myenum")),
                                                                                     new TypeProperty("pascalCaseEnumProp", new StringLiteralType("MyEnum")),
                                                                                     new TypeProperty("lowerCaseEnumUnionProp", UnionType.Create(new StringLiteralType("myenum"), new StringLiteralType("blahblah"))),
                                                                                     new TypeProperty("pascalCaseEnumUnionProp", UnionType.Create(new StringLiteralType("MyEnum"), new StringLiteralType("BlahBlah"))));
            var typeProvider = ResourceTypeProviderHelper.CreateMockTypeProvider(typeDefinition.AsEnumerable());

            var(_, _, compilation) = CompilationHelper.Compile(typeProvider, ("main.bicep", bicepFile));
            var rewriter = new TypeCasingFixerRewriter(compilation.GetEntrypointSemanticModel());

            var newProgramSyntax = rewriter.Rewrite(compilation.SyntaxTreeGrouping.EntryPoint.ProgramSyntax);

            PrintHelper.PrettyPrint(newProgramSyntax).Should().Be(
                @"resource resA 'My.Rp/resA@2020-01-01' = {
  name: 'resA'
  properties: {
    lowercaseprop: 'abc'
    camelCaseProp: 'def'
    'lowercasequoted=+.prop': 'ghi'
    'camelCaseQuoted=+.Prop': 'jkl'
    lowerCaseEnumProp: 'myenum'
    pascalCaseEnumProp: 'MyEnum'
    lowerCaseEnumUnionProp: 'myenum'
    pascalCaseEnumUnionProp: 'MyEnum'
  }
}

output myObj object = {
  lowerCaseProp: resA.properties.lowercaseprop
  camelcaseprop: resA.properties.camelCaseProp
}");
        }
        public void UnrelatedAssemblyAttributesShouldNotTrigger()
        {
            var syntaxTree    = SyntaxTreeTestFactory.FromTestFilePath("UnrelatedAssemblyAttribute.cs");
            var compilation   = CompilationHelper.CreateCompilation(new[] { syntaxTree });
            var transformable = TransformLocator.IsTransformable(compilation, syntaxTree);

            transformable.ShouldBe(false);
        }
        public void InheritedRelatedLocalAttributesShouldTrigger()
        {
            var syntaxTree    = SyntaxTreeTestFactory.FromTestFilePath("InheritedRelatedLocalAttribute.cs");
            var compilation   = CompilationHelper.CreateCompilation(new[] { syntaxTree });
            var transformable = TransformLocator.IsTransformable(compilation, syntaxTree);

            transformable.ShouldBe(true);
        }
Exemple #17
0
        public void SimpleInteger(string expressionString, int expectedFrom, int expectedTo)
        {
            var compiled = CompilationHelper.CompileAndEvaluate(expressionString);

            Assert.AreElementsEqual(
                Enumerable.Range(expectedFrom, expectedTo - expectedFrom).Select(x => new Integer(x)),
                compiled
                );
        }
        protected IDiagnostic[] GetDiagnostics(string ruleCode, string text)
        {
            var compilationResult  = CompilationHelper.Compile(text);
            var internalRuleErrors = compilationResult.Diagnostics.Where(d => d.Code == LinterAnalyzer.FailedRuleCode).ToArray();

            internalRuleErrors.Count().Should().Be(0, "There should never be linter FailedRuleCode errors");

            return(compilationResult.Diagnostics.OfType <IDiagnostic>().Where(d => d.Code == ruleCode).ToArray());
        }
Exemple #19
0
        public void HelloWorld_HasCorrectMainMethod()
        {
            var assembly = CompilationHelper.CompileFromResource("Programs.HelloWorld.light", CompilationTarget.Console);
            var main     = assembly.GetTypes().Select(t => t.GetMethod("Main")).SingleOrDefault(m => m != null);

            Assert.IsNotNull(main);
            Assert.IsTrue(main.IsStatic);
            Assert.AreEqual(assembly.EntryPoint, main);
        }
Exemple #20
0
        public void AssigningResourceToVariable_ShouldNotGenerateVariables_ChainedCondition()
        {
            var result = CompilationHelper.Compile(@"
param mode int = 0

resource storage1_1 'Microsoft.Storage/storageAccounts@2019-06-01' = if (mode == 1) {
  name: 'test11'
  location: 'eastus'
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}
resource storage1_2 'Microsoft.Storage/storageAccounts@2019-06-01' = if (mode != 1) {
  name: 'test12'
  location: 'eastus'
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}

var refResource = ref3
var ref1 = storage1_1
var ref2 = storage1_2
var ref3 = mode == 1 ? ref1 : ref2

resource storage2 'Microsoft.Storage/storageAccounts@2019-06-01' = {
  name: 'test2'
  location: 'eastus'
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
  properties: {
    allowBlobPublicAccess: refResource.properties.allowBlobPublicAccess
  }
}
");

            result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics();
            using (new AssertionScope())
            {
                result.Template.Should().NotHaveValueAtPath("$.variables", "variable should not be generated");
                result.Template.Should().HaveValueAtPath("$.resources[?(@.name == 'test2')].dependsOn",
                                                         new JArray
                {
                    "[resourceId('Microsoft.Storage/storageAccounts', 'test11')]",
                    "[resourceId('Microsoft.Storage/storageAccounts', 'test12')]"
                },
                                                         "Referenced resource should be added to depends on section");
                result.Template.Should().HaveValueAtPath("$.resources[?(@.name == 'test2')].properties.allowBlobPublicAccess",
                                                         "[if(equals(parameters('mode'), 1), reference(resourceId('Microsoft.Storage/storageAccounts', 'test11'), '2019-06-01', 'full'), reference(resourceId('Microsoft.Storage/storageAccounts', 'test12'), '2019-06-01', 'full')).properties.allowBlobPublicAccess]",
                                                         "Resource access should be in-lined");
            }
        }
Exemple #21
0
        private dynamic CompileAndGetClassWith(string functionCode)
        {
            var classCode = string.Format(@"
                public class Test
                    {0}
                end
            ", functionCode).Trim();

            return(CompilationHelper.CompileAndGetInstance(classCode, "Test"));
        }
        public void TestSetup()
        {
            solution = CompilationHelper.GetSolutionFromText(Source);

            compilation = solution.Projects.First().GetCompilationAsync().Result;
            syntaxTree  = compilation.SyntaxTrees.First();

            ifMethod     = syntaxTree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().First(m => m.Identifier.ValueText == "IfMethod");
            switchMethod = syntaxTree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().First(m => m.Identifier.ValueText == "SwitchMethod");
        }
        public void TestSetup()
        {
            solution = CompilationHelper.GetSolutionFromText(Source);

            compilation   = solution.Projects.First().GetCompilationAsync().Result;
            syntaxTree    = compilation.SyntaxTrees.First();
            semanticModel = compilation.GetSemanticModel(syntaxTree);

            methods = syntaxTree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().ToList();
        }
Exemple #24
0
        private void DoWithDiagnosticAnnotations(string text, Func <IDiagnostic, bool> filterFunc, Action <IEnumerable <IDiagnostic> > assertAction)
        {
            var result = CompilationHelper.Compile(text);

            result.Should().NotHaveDiagnosticsWithCodes(new [] { LinterAnalyzer.FailedRuleCode }, "There should never be linter FailedRuleCode errors");

            DiagnosticAssertions.DoWithDiagnosticAnnotations(
                result.Compilation.SourceFileGrouping.EntryPoint,
                result.Diagnostics.Where(filterFunc),
                assertAction);
        }
 override public void Compile(CompilationContext context)
 {
     CompilationHelper.CheckIsValue(ItemType);
     if (ItemType == typeof(Int32))
     {
         context.Emit(OpCodes.Ldind_I4);
     }
     else
     {
         throw new Exception("Unsupported type");
     }
 }
        public void DiagnosticRunnerTest_NoAnalyzer()
        {
            var runner = new DiagnosticsRunner(ImmutableArray.Create <DiagnosticAnalyzer>());

            var solution = CompilationHelper.GetSolutionFromText("");

            var compilation = solution.Projects.First().GetCompilationAsync().Result;

            var diagnosticsResult = runner.GetDiagnostics(compilation);

            diagnosticsResult.Should().HaveCount(0);
        }
Exemple #27
0
    /// <summary>
    /// </summary>
    /// <param name="context">The context.</param>
    /// <exception cref="Exception"></exception>
    public override void Compile(CompilationContext context)
    {
        CompilationHelper.CheckIsValue(ItemType);

        if (ItemType == Metadata <int> .Type)
        {
            context.Emit(OpCodes.Ldind_I4);
        }
        else
        {
            throw new Exception("Unsupported type");
        }
    }
        public void If_ResLocationIs_StringLiteral_ShouldFail_WithFixes()
        {
            var result = CompilationHelper.Compile(@"
                resource storageaccount 'Microsoft.Storage/storageAccounts@2021-02-01' = {
                  name: 'name'
                  location: 'westus'
                  kind: 'StorageV2'
                  sku: {
                    name: 'Premium_LRS'
                  }
                }
            ");

            result.Diagnostics.Should().HaveDiagnostics(new[]
Exemple #29
0
        public void TemplateEmitter_should_not_dispose_text_writer()
        {
            var(_, _, compilation) = CompilationHelper.Compile(string.Empty);

            var stringBuilder = new StringBuilder();
            var stringWriter  = new StringWriter(stringBuilder);

            var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), BicepTestConstants.EmitterSettings);

            emitter.Emit(stringWriter);

            // second write should succeed if stringWriter wasn't closed
            emitter.Emit(stringWriter);
        }
        public void If_ResLocationIs_Global_CaseInsensitive_ShouldPass()
        {
            var result = CompilationHelper.Compile(@"
                resource appInsightsComponents 'Microsoft.Insights/components@2020-02-02-preview' = {
                  name: 'name'
                  location: 'GLOBAL'
                  kind: 'web'
                  properties: {
                    Application_Type: 'web'
                  }
                }"
                                                   );

            result.Diagnostics.Should().BeEmpty();
        }