Skip to content

Commit 8801004

Browse files
Merge pull request #18 from jonathanalgar/best-practices-large-input-files
Beyond the rules: info-level guidance for best practices > guidance on large binary files
2 parents 2cb233a + 45086e9 commit 8801004

5 files changed

Lines changed: 59 additions & 8 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414

1515
When you want to extend your ODC apps with custom C# code, you do so with the [External Libraries SDK](https://success.outsystems.com/documentation/outsystems_developer_cloud/building_apps/extend_your_apps_with_custom_code/external_libraries_sdk_readme/). This SDK allows you to write C# code that you can call from your ODC apps.
1616

17-
Although IntelliSense in your IDE guides the available SDK decorators and their syntax, it does not guide the rules you must follow (for example, on [naming](https://www.outsystems.com/tk/redirect?g=OS-ELG-MODL-05019) and [design decisions](https://www.outsystems.com/tk/redirect?g=OS-ELG-MODL-05018)). This guidance is provided when uploading your project's built assembly to the ODC Portal, where you get feedback on rule violations. **Using this component brings that feedback forward and gives you real-time feedback on compliance with the rules as you write the code.**
17+
Although IntelliSense in your IDE guides the available SDK decorators and their syntax, it does not guide the rules you must follow (for example, on [naming](https://www.outsystems.com/tk/redirect?g=OS-ELG-MODL-05019) and [design decisions](https://www.outsystems.com/tk/redirect?g=OS-ELG-MODL-05018)). This guidance is provided when uploading your project's built assembly to the ODC Portal, where you get feedback on rule violations. **Using this component brings that feedback forward and gives you real-time feedback on compliance with the rules as you write the code. You also get real-time guidance on best practices.**
1818

1919
### Technical Primer
2020

21-
When you upload your project's built assembly to the ODC Portal, it does not have access to the underlying code—the ODC Portal checks compliance with the rules using the assembly's metadata.
21+
When you upload your project's built assembly to the ODC Portal, it does not have access to the underlying code—the ODC Portal checks compliance with the rules by reflecting on assembly's metadata.
2222

2323
This component, built from scratch, implements the rules using the rich code analysis APIs of [Roslyn](https://github.com/dotnet/roslyn), the .NET compiler.
2424

src/CustomCode-Analyzer.Vsix/source.extension.vsixmanifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
33
<Metadata>
4-
<Identity Id="CustomCode_Analyzer.Vsix.e1c79fe3-d19f-4bf9-9c0c-57ba1f95b494" Version="0.1.2" Language="en-US" Publisher="Jonathan Algar"/>
4+
<Identity Id="CustomCode_Analyzer.Vsix.e1c79fe3-d19f-4bf9-9c0c-57ba1f95b494" Version="0.1.3" Language="en-US" Publisher="Jonathan Algar"/>
55
<DisplayName>ODC Custom Code Analyzer</DisplayName>
66
<Description xml:space="preserve">Get feedback on your OutSytems Developer Cloud (ODC) custom C# code as you code.</Description>
77
<MoreInfo>https://github.com/jonathanalgar/CustomCode-Analyzer</MoreInfo>

src/CustomCode-Analyzer/Analyzer.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public static class DiagnosticIds
4242
public const string UnsupportedParameterType = "UnsupportedParameterType";
4343
public const string UnsupportedDefaultValue = "UnsupportedDefaultValue";
4444
public const string PotentialStatefulImplementation = "PotentialStatefulImplementation";
45+
public const string InputSizeLimit = "InputSizeLimit";
4546
}
4647

4748
/// <summary>
@@ -300,11 +301,21 @@ public static class Categories
300301
title: "Possible stateful behavior",
301302
messageFormat: "The class '{0}' contains static members ({1}) which could persist state between calls. External libraries should be designed to be stateless.",
302303
category: Categories.Design,
303-
defaultSeverity: DiagnosticSeverity.Info,
304+
defaultSeverity: DiagnosticSeverity.Warning,
304305
isEnabledByDefault: true,
305306
description: "External libraries should be designed to be stateless. Consider passing state information as method parameters instead of storing it in fields.",
306307
helpLinkUri: "https://success.outsystems.com/documentation/outsystems_developer_cloud/building_apps/extend_your_apps_with_custom_code/external_libraries_sdk_readme/#architecture");
307308

309+
private static readonly DiagnosticDescriptor InputSizeLimitRule = new(
310+
DiagnosticIds.InputSizeLimit,
311+
title: "Possible input size limit",
312+
messageFormat: "This method accepts binary data. Note that external libraries have a 5.5MB total input size limit. For large files, use a REST API endpoint or file URL instead.",
313+
category: Categories.Design,
314+
defaultSeverity: DiagnosticSeverity.Warning,
315+
isEnabledByDefault: true,
316+
description: "External libraries have a 5.5MB total input size limit. For large binary files, expose them through a REST API endpoint in your app or provide a URL to download them.",
317+
helpLinkUri: "https://success.outsystems.com/documentation/outsystems_developer_cloud/building_apps/extend_your_apps_with_custom_code/external_libraries_sdk_readme/#use-with-large-binary-files");
318+
308319
/// <summary>
309320
/// Returns the full set of DiagnosticDescriptors that this analyzer is capable of producing.
310321
/// </summary>
@@ -332,7 +343,8 @@ public static class Categories
332343
MissingStructureDecorationRule,
333344
UnsupportedParameterTypeRule,
334345
UnsupportedDefaultValueRule,
335-
PotentialStatefulImplementationRule);
346+
PotentialStatefulImplementationRule,
347+
InputSizeLimitRule);
336348

337349
/// <summary>
338350
/// Entry point for the analyzer. Initializes analysis by setting up compilation-level
@@ -706,6 +718,16 @@ private static void AnalyzeMethod(SymbolAnalysisContext context, IMethodSymbol m
706718
}
707719
}
708720

721+
// Check for potential input size limit issues
722+
if (parameter.Type is IArrayTypeSymbol arrayType && arrayType.ElementType.SpecialType == SpecialType.System_Byte)
723+
{
724+
context.ReportDiagnostic(
725+
Diagnostic.Create(
726+
InputSizeLimitRule,
727+
methodSyntax.GetLocation()));
728+
break;
729+
}
730+
709731
// Check if the default value is valid (compile-time constant and supported type)
710732
if (parameter.HasExplicitDefaultValue &&
711733
!IsValidParameterDefaultValue(parameter) &&

src/CustomCode-Analyzer/CustomCode-Analyzer.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
<LangVersion>latest</LangVersion>
99
<RootNamespace>CustomCode_Analyzer</RootNamespace>
1010
<PackageId>CustomCode.Analyzer</PackageId>
11-
<Version>0.1.2</Version>
12-
<AssemblyVersion>0.1.2</AssemblyVersion>
13-
<FileVersion>0.1.2</FileVersion>
11+
<Version>0.1.3</Version>
12+
<AssemblyVersion>0.1.3</AssemblyVersion>
13+
<FileVersion>0.1.3</FileVersion>
1414
<Authors>Jonathan Algar</Authors>
1515
<Product>OutSystems Developer Cloud (ODC) Custom Code Analyzer</Product>
1616
<Description>Get feedback on your OutSytems Developer Cloud (ODC) custom C# code as you code.</Description>

tests/CustomCode-Analyzer.Tests/AnalyzerTests.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,35 @@ public int GetTotalCalculations()
13831383

13841384
await CSharpAnalyzerVerifier<Analyzer>.VerifyAnalyzerAsync(test, TestContext, skipSDKreference: false, expected);
13851385
}
1386+
1387+
// --------------------- InputSizeLimitRule --------------------------------
1388+
[TestMethod]
1389+
public async Task InputSizeLimitRule_ShowsInfo()
1390+
{
1391+
var test = @"
1392+
namespace TestNamespace
1393+
{
1394+
[OSInterface]
1395+
public interface IDocumentProcessor
1396+
{
1397+
void ProcessDocument(byte[] documentData);
1398+
void ProcessMetadata(string metadata);
1399+
}
1400+
1401+
public class DocumentProcessor : IDocumentProcessor
1402+
{
1403+
public void ProcessDocument(byte[] documentData) { }
1404+
public void ProcessMetadata(string metadata) { }
1405+
}
1406+
}";
1407+
var expected = CSharpAnalyzerVerifier<Analyzer>
1408+
.Diagnostic(DiagnosticIds.InputSizeLimit)
1409+
.WithSpan(7, 9, 7, 51);
1410+
1411+
await CSharpAnalyzerVerifier<Analyzer>.VerifyAnalyzerAsync(test, TestContext, skipSDKreference: false, expected);
1412+
}
1413+
// -------------------------------------------------------------------------
1414+
13861415
// ----------------------------------------------- MIXED TESTS!
13871416
[TestMethod]
13881417
public async Task ComplexScenario_MultipleNamingAndStructureIssues_ReportsWarnings()

0 commit comments

Comments
 (0)