Skip to content

fix: ajustes pós-merge PR #99 (Devin Review, CodeQL, duplicação)#100

Merged
github-actions[bot] merged 1 commit into
mainfrom
feature/devin-20260712-sonar-final-fix-v2
Jul 12, 2026
Merged

fix: ajustes pós-merge PR #99 (Devin Review, CodeQL, duplicação)#100
github-actions[bot] merged 1 commit into
mainfrom
feature/devin-20260712-sonar-final-fix-v2

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

All Submissions:

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?

New Feature Submissions:

  1. Does your submission pass tests?
  2. Have you lint your code locally prior to submission?

Changes to Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

Summary

Ajustes no PR #99 para resolver os apontamentos do Devin Review, CodeQL e SonarCloud.

Correções:

  • EvolutionChunkDecoder.Parse agora atribui Remaining no caminho de sucesso, permitindo que TafDecoder.DecodeEvolutions processe múltiplas evoluções corretamente
  • ParseEntitiesChunk voltou a retornar string e o retorno é utilizado
  • CloudChunkDecoder TAF passou a usar Dictionary para mapeamento de CloudAmount/CloudType, reduzindo duplicação com o METAR
  • Conversão layerHeight.Value * 100.0 (double) para evitar alerta de overflow do CodeQL
  • ApplyDecodedData (METAR/TAF) usa TryGetValue para evitar acesso duplo ao dicionário
  • Validação de result não nulo em ApplyDecodedChunk (TAF)

Validação

  • dotnet build MetarDecoder.sln --configuration Release OK
  • dotnet test tests/Metar.Decoder.Tests/ (net8.0/net10.0) — 242/242 passando
  • dotnet test tests/Taf.Decoder.Tests/ (net8.0/net10.0) — 192/192 passando

Link to Devin session: https://app.devin.ai/sessions/94a258020ea4488c8eecc672035d0da1
Requested by: @afonsoft


Open in Devin Review

- Corrige Remaining não setado no success path de EvolutionChunkDecoder.Parse
- Converte int*100 para double para evitar overflow CodeQL
- Usa TryGetValue em ApplyDecodedData (METAR/TAF)
- Valida result não nulo em ApplyDecodedChunk (TAF)
- Reduz duplicação em CloudChunkDecoder TAF com Dictionary mapping

Co-Authored-By: Afonso Dutra Nogueira Filho <[email protected]>
@afonsoft afonsoft self-assigned this Jul 12, 2026
@afonsoft
afonsoft self-requested a review July 12, 2026 18:49
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@afonsoft

Copy link
Copy Markdown
Owner

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@sonarqubecloud

Copy link
Copy Markdown

@github-actions
github-actions Bot merged commit 8e6ca3d into main Jul 12, 2026
19 of 22 checks passed
@github-actions

Copy link
Copy Markdown

Qodana Community for .NET

5 new problems were found

Inspection name Severity Problems
Unused local variable 🔶 Warning 1
Use preferred style of 'new' expression when created type is evident ◽️ Notice 2
Dictionary lookup can be simplified with 'GetValueOrDefault' ◽️ Notice 2

💡 Qodana analysis was run in the pull request mode: only the changed files were checked

View the detailed Qodana report

To be able to view the detailed Qodana report, you can either:

To get *.log files or any other Qodana artifacts, run the action with upload-result option set to true,
so that the action will upload the files as the job artifacts:

      - name: 'Qodana Scan'
        uses: JetBrains/[email protected]
        with:
          upload-result: true
Contact Qodana team

Contact us at [email protected]

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 potential issues.

Open in Devin Review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 CAVOK flag is unconditionally reset to false inside evolution entity parsing loop

At EvolutionChunkDecoder.cs:115, _withCavok is set to false on every iteration of the decoder chain loop, even though ResolveEntityName at line 166 may set it to true when a CAVOK visibility chunk is encountered. This means if the VisibilityChunkDecoder runs and sets _withCavok = true via ResolveEntityName, the next decoder iteration immediately resets it to false. This is a pre-existing issue (not introduced by this PR) but the PR touches the surrounding method, so it's worth noting. The impact may be limited since _withCavok is primarily used in AddEvolution to set newEvolution.Cavok, which would have already been called by that point.

(Refers to line 115)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

}

ParseEntitiesChunk(evolution, remaining, decodedTaf);
Remaining = ParseEntitiesChunk(evolution, remaining, decodedTaf);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Pre-existing bug fixed: Remaining property was never set on successful evolution parse

In the old code, EvolutionChunkDecoder.Parse only set Remaining when the regex match failed (found.Count <= 1). When the match succeeded, ParseEntitiesChunk was called but Remaining was never updated. The caller in TafDecoder.cs:166-167 reads evolutionDecoder.Remaining after every call in a while loop. On the first successful parse, Remaining would be null (its default), causing the while loop's !string.IsNullOrEmpty(remainingTaf) check to exit early — potentially dropping all subsequent evolution blocks (BECMG, TEMPO, FM) from the decoded TAF. The new code at line 95 correctly sets Remaining to the return value of ParseEntitiesChunk, which is the text left after entity decoders have consumed their portions. This is a meaningful bug fix.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +160 to 163
if (decodedData.TryGetValue(ExceptionKey, out var exception) && exception is MetarChunkDecoderException metarChunkDecoderException)
{
decodedMetar.AddDecodingException((MetarChunkDecoderException)decodedData[ExceptionKey]);
decodedMetar.AddDecodingException(metarChunkDecoderException);
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Subtle behavioral change: hard cast replaced with pattern match silently skips non-matching types

The old code used (MetarChunkDecoderException)decodedData[ExceptionKey] which would throw InvalidCastException if the value was not the expected type. The new code uses exception is MetarChunkDecoderException metarChunkDecoderException which silently skips if the type doesn't match. In practice this is safe because ExceptionKey is only ever populated with a MetarChunkDecoderException at MetarDecoder.cs:202, but it is a semantic change from "crash on unexpected type" to "silently ignore unexpected type." This is arguably more robust but worth being aware of.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +14 to +28
private static readonly Dictionary<string, CloudLayer.CloudAmount> AmountMap = new Dictionary<string, CloudLayer.CloudAmount>
{
{ "FEW", CloudLayer.CloudAmount.FEW },
{ "SCT", CloudLayer.CloudAmount.SCT },
{ "BKN", CloudLayer.CloudAmount.BKN },
{ "OVC", CloudLayer.CloudAmount.OVC },
{ "VV", CloudLayer.CloudAmount.VV },
};

private static readonly Dictionary<string, CloudLayer.CloudType> TypeMap = new Dictionary<string, CloudLayer.CloudType>
{
{ "CB", CloudLayer.CloudType.CB },
{ "TCU", CloudLayer.CloudType.TCU },
{ "///", CloudLayer.CloudType.CannotMeasure },
};

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Inconsistent refactoring style between Metar and Taf CloudChunkDecoders

The Taf CloudChunkDecoder was refactored to use static Dictionary lookups (AmountMap, TypeMap) instead of switch expressions, while the Metar CloudChunkDecoder at src/Metar.Decoder/ChunkDecoder/CloudChunkDecoder.cs:84-105 retains the original switch expression approach (ParseCloudAmount, ParseCloudType). Both decoders serve the same purpose for their respective domains and the AGENTS.md rule S2 says "Adicionar novo ChunkDecoder → seguir padrão existente." Having two different patterns for the same logic across Metar and Taf may cause confusion for future contributors.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@afonsoft
afonsoft deleted the feature/devin-20260712-sonar-final-fix-v2 branch July 13, 2026 01:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant