• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

polserver / polserver / 16578783200

28 Jul 2025 07:48PM UTC coverage: 59.79% (+0.2%) from 59.58%
16578783200

push

github

web-flow
Short Circuit Optimizer (#797)

* first working short curcuit for && and or
creates jumps after each expressions to skip the following

* fixed valuestack when short circuit jmp does not jump

* use specialized instructions for short circuit && and ||

1: lhs
2: logical jump if false/true goto 4 <- if jmp do logical convert
3: rhs
4: logical convert
5: rest

logical convert is needed since "normal" && || operations convert isTrue
to BLong

added BObjectRef BObjectImp set specialization to remove noise

* fixed converted objimp when jump on false values

* first version of short circuit warning
should be moved to analyzer
added whitelist of module functions which have no sideeffect to reduce
the number of warnings

* moved warning visitor to analyzer and added it as extra compile step
fixed sourceline print and cache the content

* missing include, unused member

* included the correct header

* ecompile.cfg to activate and warn
ecompile cmdline arg to activate it
run all tests also with it active
fixed that only the most right side statement was checked

* ecompile cmdline

* increase ecompile version
cleanup

* compilation error

* missing header

* allow -S- to deactivate shortcircuit like the other params do

* extended whitelist functions

* revert fileformat version increase
fixed escript test cmake

* use the correct arg

* escript testoutput can now be different if shortcircuit is active

* docs

* additional test

* addressed comments

210 of 239 new or added lines in 16 files covered. (87.87%)

1 existing line in 1 file now uncovered.

43653 of 73010 relevant lines covered (59.79%)

466031.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.71
/pol-core/bscript/compiler/file/SourceLocation.cpp
1
#include "SourceLocation.h"
2

3
#include "bscript/compiler/Antlr4Inc.h"
4

5
#include "bscript/compiler/file/SourceFileIdentifier.h"
6
#include "clib/filecont.h"
7
#include "clib/logfacility.h"
8

9
#include <iterator>
10

11
#include <climits>
12

13
namespace Pol::Bscript::Compiler
14
{
15
Position calculate_end_position( const antlr4::Token* symbol )
1,038,502✔
16
{
17
  if ( !symbol )
1,038,502✔
18
  {
19
    return Position{ 0, 0, 0 };
×
20
  }
21
  auto line = symbol->getLine();
1,038,502✔
22
  auto character = symbol->getCharPositionInLine() + 1;
1,038,502✔
23
  const auto& str = symbol->getText();
1,038,502✔
24
  const auto size = str.size();
1,038,502✔
25

26
  for ( size_t i = 0; i < size; i++ )
4,648,239✔
27
  {
28
    if ( str[i] == '\r' && i + 1 < size && str[i + 1] == '\n' )
3,609,737✔
29
    {
30
      ++line;
×
31
      character = 1;
×
32
    }
33
    else if ( str[i] == '\r' )
3,609,737✔
34
    {
35
      ++line;
×
36
      character = 1;
×
37
    }
38
    else if ( str[i] == '\n' )
3,609,737✔
39
    {
40
      ++line;
279✔
41
      character = 1;
279✔
42
    }
43
    else
44
      ++character;
3,609,458✔
45
  }
46

47
  return Position{ line, character, symbol->getTokenIndex() };
1,038,502✔
48
}
1,038,502✔
49

50
Range::Range( Position start, Position end ) : start( std::move( start ) ), end( std::move( end ) )
3,154✔
51
{
52
}
3,154✔
53

54
Range::Range( const antlr4::ParserRuleContext& ctx )
941,959✔
55
    : start( Position{ ctx.getStart()->getLine(), ctx.getStart()->getCharPositionInLine() + 1,
941,959✔
56
                       ctx.getStart()->getTokenIndex() } ),
941,959✔
57
      end( calculate_end_position( ctx.getStop() ) )
941,959✔
58
{
59
}
941,959✔
60

61
Range::Range( const antlr4::tree::TerminalNode& ctx )
91,844✔
62
    : start( Position{ ctx.getSymbol()->getLine(), ctx.getSymbol()->getCharPositionInLine() + 1,
91,844✔
63
                       ctx.getSymbol()->getTokenIndex() } ),
91,844✔
64
      end( calculate_end_position( ctx.getSymbol() ) )
91,844✔
65
{
66
}
91,844✔
67

68
Range::Range( const antlr4::Token* token )
4,699✔
69
    : start( Position{ token->getLine(), token->getCharPositionInLine() + 1,
4,699✔
70
                       token->getTokenIndex() } ),
4,699✔
71
      end( calculate_end_position( token ) )
4,699✔
72
{
73
}
4,699✔
74

75
SourceLocation::SourceLocation( const SourceFileIdentifier* source_file_identifier,
3,148✔
76
                                size_t line_number, size_t character_column )
3,148✔
77
    : source_file_identifier( source_file_identifier ),
3,148✔
78
      range( Position{ line_number, character_column, 0 },
3,148✔
79
             Position{ std::numeric_limits<size_t>::max(), std::numeric_limits<size_t>::max(),
80
                       std::numeric_limits<size_t>::max() } )
81
{
82
}
3,148✔
83

84
SourceLocation::SourceLocation( const SourceFileIdentifier* source_file_identifier,
×
85
                                const Range& range )
×
86
    : source_file_identifier( source_file_identifier ), range( range )
×
87
{
88
}
×
89

90
SourceLocation::SourceLocation( const SourceFileIdentifier* source_file_identifier,
941,607✔
91
                                const antlr4::ParserRuleContext& ctx )
941,607✔
92
    : source_file_identifier( source_file_identifier ), range( ctx )
941,607✔
93
{
94
}
941,607✔
95

96
SourceLocation::SourceLocation( const SourceFileIdentifier* source_file_identifier,
47,942✔
97
                                const antlr4::tree::TerminalNode& ctx )
47,942✔
98
    : source_file_identifier( source_file_identifier ), range( ctx )
47,942✔
99
{
100
}
47,942✔
101

102
bool Range::contains( const Position& position ) const
1,674✔
103
{
104
  return contains( position.line_number, position.character_column );
1,674✔
105
}
106

107
bool Range::contains( size_t line_number, size_t character_column ) const
1,674✔
108
{
109
  if ( line_number < start.line_number || line_number > end.line_number )
1,674✔
110
  {
111
    return false;
220✔
112
  }
113
  if ( line_number == start.line_number && character_column < start.character_column )
1,454✔
114
  {
115
    return false;
×
116
  }
117
  if ( line_number == end.line_number && character_column > end.character_column )
1,454✔
118
  {
119
    return false;
×
120
  }
121
  return true;
1,454✔
122
}
123

124
bool Range::contains( const Range& otherRange ) const
×
125
{
126
  if ( otherRange.start.line_number < start.line_number ||
×
127
       otherRange.end.line_number < start.line_number )
×
128
  {
129
    return false;
×
130
  }
131
  if ( otherRange.start.line_number > end.line_number ||
×
132
       otherRange.end.line_number > end.line_number )
×
133
  {
134
    return false;
×
135
  }
136
  if ( otherRange.start.line_number == start.line_number &&
×
137
       otherRange.start.character_column < start.character_column )
×
138
  {
139
    return false;
×
140
  }
141
  if ( otherRange.end.line_number == end.line_number &&
×
142
       otherRange.end.character_column > end.character_column )
×
143
  {
144
    return false;
×
145
  }
146
  return true;
×
147
}
148

149
void SourceLocation::debug( const std::string& msg ) const
×
150
{
151
  ERROR_PRINTLN( "{}: {}", ( *this ), msg );
×
152
}
×
153

154
void SourceLocation::internal_error( const std::string& msg ) const
×
155
{
156
  ERROR_PRINTLN( "{}: {}", ( *this ), msg );
×
157
  throw std::runtime_error( msg );
×
158
}
159

160
void SourceLocation::internal_error( const std::string& msg, const SourceLocation& related ) const
×
161
{
162
  ERROR_PRINTLN( "{}: {}\n  See also: {}", ( *this ), msg, related );
×
163
  throw std::runtime_error( msg );
×
164
}
165

166
std::string SourceLocation::getSourceLine() const
16✔
167
{
168
  std::string lines;
16✔
169
  if ( !range.start.line_number )
16✔
NEW
170
    return {};
×
171
  auto& content = source_file_identifier->getLines();
16✔
172
  for ( size_t i = range.start.line_number - 1; i < range.end.line_number && i < content.size();
32✔
173
        ++i )
174
  {
175
    if ( lines.size() )
16✔
NEW
176
      lines += '\n';
×
177
    lines += content[i];
16✔
178
  }
179

180
  return lines;
16✔
181
}
16✔
182

183
}  // namespace Pol::Bscript::Compiler
184

185
fmt::format_context::iterator fmt::formatter<Pol::Bscript::Compiler::SourceLocation>::format(
799✔
186
    const Pol::Bscript::Compiler::SourceLocation& l, fmt::format_context& ctx ) const
187
{
188
  std::string tmp = l.source_file_identifier->pathname;
799✔
189
  if ( l.range.start.line_number || l.range.start.character_column )
799✔
190
    fmt::format_to( std::back_inserter( tmp ), ":{}:{}", l.range.start.line_number,
1,598✔
191
                    l.range.start.character_column );
799✔
192
  return fmt::formatter<std::string>::format( tmp, ctx );
1,598✔
193
}
799✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc