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); } }
[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); }
/// <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); }
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); }
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); } }
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" } } }); }
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); }
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()); }
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); }
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"); } }
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(); }
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); }
/// <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[]
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(); }