@@ -2,6 +2,11 @@ use crate::span::Span;
2
2
use crate :: { parser:: Rule , types:: MaybeResolvedType } ;
3
3
use inflector:: cases:: classcase:: to_class_case;
4
4
use inflector:: cases:: snakecase:: to_snake_case;
5
+ use line_col:: LineColLookup ;
6
+ use source_span:: {
7
+ fmt:: { Formatter , Style } ,
8
+ Position ,
9
+ } ;
5
10
use thiserror:: Error ;
6
11
7
12
macro_rules! check {
@@ -137,6 +142,34 @@ impl<'sc> CompileWarning<'sc> {
137
142
self . span . end_pos ( ) . line_col ( ) . into ( ) ,
138
143
)
139
144
}
145
+
146
+ pub fn format ( & self , fmt : & mut Formatter ) -> source_span:: fmt:: Formatted {
147
+ let input = self . span . input ( ) ;
148
+ let chars = input. chars ( ) . map ( |x| -> Result < _ , ( ) > { Ok ( x) } ) ;
149
+
150
+ let metrics = source_span:: DEFAULT_METRICS ;
151
+ let buffer = source_span:: SourceBuffer :: new ( chars, Position :: default ( ) , metrics) ;
152
+
153
+ for c in buffer. iter ( ) {
154
+ let _ = c. unwrap ( ) ; // report eventual errors.
155
+ }
156
+
157
+ let ( start_pos, end_pos) = self . span ( ) ;
158
+ let lookup = LineColLookup :: new ( input) ;
159
+ let ( start_line, start_col) = lookup. get ( start_pos) ;
160
+ let ( end_line, end_col) = lookup. get ( end_pos - 1 ) ;
161
+
162
+ let err_start = Position :: new ( start_line - 1 , start_col - 1 ) ;
163
+ let err_end = Position :: new ( end_line - 1 , end_col - 1 ) ;
164
+ let err_span = source_span:: Span :: new ( err_start, err_end, err_end. next_column ( ) ) ;
165
+ fmt. add (
166
+ err_span,
167
+ Some ( self . to_friendly_warning_string ( ) ) ,
168
+ Style :: Warning ,
169
+ ) ;
170
+
171
+ fmt. render ( buffer. iter ( ) , buffer. span ( ) , & metrics) . unwrap ( )
172
+ }
140
173
}
141
174
142
175
#[ derive( Debug , Clone ) ]
@@ -390,10 +423,15 @@ pub enum CompileError<'sc> {
390
423
ReassignmentToNonVariable {
391
424
name : & ' sc str ,
392
425
kind : & ' sc str ,
393
- span : Span < ' sc > ,
426
+ decl_span : Span < ' sc > ,
427
+ usage_span : Span < ' sc > ,
428
+ } ,
429
+ #[ error( "Assignment to immutable variable. Variable {name} is not declared as mutable." ) ]
430
+ AssignmentToNonMutable {
431
+ name : & ' sc str ,
432
+ decl_span : Span < ' sc > ,
433
+ usage_span : Span < ' sc > ,
394
434
} ,
395
- #[ error( "Assignment to immutable variable. Variable {0} is not declared as mutable." ) ]
396
- AssignmentToNonMutable ( String , Span < ' sc > ) ,
397
435
#[ error(
398
436
"Generic type \" {name}\" is not in scope. Perhaps you meant to specify type parameters in \
399
437
the function signature? For example: \n `fn \
@@ -631,7 +669,8 @@ pub enum CompileError<'sc> {
631
669
"Function \" {method_name}\" expects {expected} arguments but you provided {received}."
632
670
) ]
633
671
TooManyArgumentsForFunction {
634
- span : Span < ' sc > ,
672
+ decl_span : Span < ' sc > ,
673
+ usage_span : Span < ' sc > ,
635
674
method_name : & ' sc str ,
636
675
expected : usize ,
637
676
received : usize ,
@@ -640,7 +679,8 @@ pub enum CompileError<'sc> {
640
679
"Function \" {method_name}\" expects {expected} arguments but you provided {received}."
641
680
) ]
642
681
TooFewArgumentsForFunction {
643
- span : Span < ' sc > ,
682
+ decl_span : Span < ' sc > ,
683
+ usage_span : Span < ' sc > ,
644
684
method_name : & ' sc str ,
645
685
expected : usize ,
646
686
received : usize ,
@@ -792,8 +832,8 @@ impl<'sc> CompileError<'sc> {
792
832
PredicateMainDoesNotReturnBool ( span) => span,
793
833
NoScriptMainFunction ( span) => span,
794
834
MultipleScriptMainFunctions ( span) => span,
795
- ReassignmentToNonVariable { span , .. } => span ,
796
- AssignmentToNonMutable ( _ , span ) => span ,
835
+ ReassignmentToNonVariable { usage_span , .. } => usage_span ,
836
+ AssignmentToNonMutable { usage_span , .. } => usage_span ,
797
837
TypeParameterNotInTypeScope { span, .. } => span,
798
838
MultipleImmediates ( span) => span,
799
839
MismatchedTypeInTrait { span, .. } => span,
@@ -848,8 +888,8 @@ impl<'sc> CompileError<'sc> {
848
888
UnnecessaryEnumInstantiator { span, .. } => span,
849
889
TraitNotFound { span, .. } => span,
850
890
InvalidExpressionOnLhs { span, .. } => span,
851
- TooManyArgumentsForFunction { span , .. } => span ,
852
- TooFewArgumentsForFunction { span , .. } => span ,
891
+ TooManyArgumentsForFunction { usage_span , .. } => usage_span ,
892
+ TooFewArgumentsForFunction { usage_span , .. } => usage_span ,
853
893
InvalidAbiType { span, .. } => span,
854
894
InvalidNumberOfAbiParams { span, .. } => span,
855
895
NotAnAbi { span, .. } => span,
@@ -870,4 +910,139 @@ impl<'sc> CompileError<'sc> {
870
910
self . internal_span ( ) . end_pos ( ) . line_col ( ) . into ( ) ,
871
911
)
872
912
}
913
+
914
+ pub fn format ( & self , fmt : & mut Formatter ) -> source_span:: fmt:: Formatted {
915
+ match self {
916
+ CompileError :: AssignmentToNonMutable {
917
+ name,
918
+ decl_span,
919
+ usage_span,
920
+ } => self . format_one_hint_one_err (
921
+ fmt,
922
+ decl_span,
923
+ format ! (
924
+ "Variable {} not declared as mutable. Try adding 'mut'." ,
925
+ name
926
+ ) ,
927
+ usage_span,
928
+ format ! ( "Assignment to immutable variable {}." , name) ,
929
+ ) ,
930
+ CompileError :: TooFewArgumentsForFunction {
931
+ decl_span,
932
+ usage_span,
933
+ method_name,
934
+ expected,
935
+ received,
936
+ } => self . format_one_hint_one_err (
937
+ fmt,
938
+ decl_span,
939
+ format ! ( "Function {} declared here." , method_name) ,
940
+ usage_span,
941
+ format ! (
942
+ "Function {} expected {} arguments and recieved {}." ,
943
+ method_name, expected, received
944
+ ) ,
945
+ ) ,
946
+ CompileError :: TooManyArgumentsForFunction {
947
+ decl_span,
948
+ usage_span,
949
+ method_name,
950
+ expected,
951
+ received,
952
+ } => self . format_one_hint_one_err (
953
+ fmt,
954
+ decl_span,
955
+ format ! ( "Function {} declared here." , method_name) ,
956
+ usage_span,
957
+ format ! (
958
+ "Function {} expected {} arguments and recieved {}." ,
959
+ method_name, expected, received
960
+ ) ,
961
+ ) ,
962
+ CompileError :: ReassignmentToNonVariable {
963
+ name,
964
+ kind,
965
+ decl_span,
966
+ usage_span,
967
+ } => self . format_one_hint_one_err (
968
+ fmt,
969
+ decl_span,
970
+ format ! ( "Symbol {} declared here." , name) ,
971
+ usage_span,
972
+ format ! ( "Attempted to reassign to a symbol that is not a variable. Symbol {} is not a mutable \
973
+ variable, it is a {}.", name, kind)
974
+ ) ,
975
+ _ => self . format_err_simple ( fmt) ,
976
+ }
977
+ }
978
+
979
+ fn format_err_simple ( & self , fmt : & mut Formatter ) -> source_span:: fmt:: Formatted {
980
+ let input = self . internal_span ( ) . input ( ) ;
981
+ let chars = input. chars ( ) . map ( Result :: < _ , String > :: Ok ) ;
982
+
983
+ let metrics = source_span:: DEFAULT_METRICS ;
984
+ let buffer = source_span:: SourceBuffer :: new ( chars, Position :: default ( ) , metrics) ;
985
+
986
+ for c in buffer. iter ( ) {
987
+ let _ = c. unwrap ( ) ; // report eventual errors.
988
+ }
989
+
990
+ let ( start_pos, end_pos) = self . span ( ) ;
991
+ let lookup = LineColLookup :: new ( input) ;
992
+ let ( start_line, start_col) = lookup. get ( start_pos) ;
993
+ let ( end_line, end_col) = lookup. get ( if end_pos == 0 { 0 } else { end_pos - 1 } ) ;
994
+
995
+ let err_start = Position :: new ( start_line - 1 , start_col - 1 ) ;
996
+ let err_end = Position :: new ( end_line - 1 , end_col - 1 ) ;
997
+ let err_span = source_span:: Span :: new ( err_start, err_end, err_end. next_column ( ) ) ;
998
+ fmt. add (
999
+ err_span,
1000
+ Some ( self . to_friendly_error_string ( ) ) ,
1001
+ Style :: Error ,
1002
+ ) ;
1003
+
1004
+ fmt. render ( buffer. iter ( ) , buffer. span ( ) , & metrics) . unwrap ( )
1005
+ }
1006
+
1007
+ fn format_one_hint_one_err (
1008
+ & self ,
1009
+ fmt : & mut Formatter ,
1010
+ hint_span : & Span < ' sc > ,
1011
+ hint_message : String ,
1012
+ err_span : & Span < ' sc > ,
1013
+ err_message : String ,
1014
+ ) -> source_span:: fmt:: Formatted {
1015
+ self . format_one ( fmt, hint_span. clone ( ) , Style :: Note , hint_message) ;
1016
+ self . format_one ( fmt, err_span. clone ( ) , Style :: Error , err_message) ;
1017
+
1018
+ let span = crate :: utils:: join_spans ( hint_span. clone ( ) , err_span. clone ( ) ) ;
1019
+ let input = span. input ( ) ;
1020
+ let chars = input. chars ( ) . map ( Result :: < _ , String > :: Ok ) ;
1021
+ let metrics = source_span:: DEFAULT_METRICS ;
1022
+ let buffer = source_span:: SourceBuffer :: new ( chars, Position :: default ( ) , metrics) ;
1023
+ for c in buffer. iter ( ) {
1024
+ let _ = c. unwrap ( ) ; // report eventual errors.
1025
+ }
1026
+
1027
+ fmt. render ( buffer. iter ( ) , buffer. span ( ) , & metrics) . unwrap ( )
1028
+ }
1029
+
1030
+ fn format_one (
1031
+ & self ,
1032
+ fmt : & mut Formatter ,
1033
+ span : Span < ' sc > ,
1034
+ style : source_span:: fmt:: Style ,
1035
+ friendly_string : String ,
1036
+ ) {
1037
+ let input = span. input ( ) ;
1038
+ let ( start_pos, end_pos) = ( span. start ( ) , span. end ( ) ) ;
1039
+ let lookup = LineColLookup :: new ( input) ;
1040
+ let ( start_line, start_col) = lookup. get ( start_pos) ;
1041
+ let ( end_line, end_col) = lookup. get ( if end_pos == 0 { 0 } else { end_pos - 1 } ) ;
1042
+
1043
+ let err_start = Position :: new ( start_line - 1 , start_col - 1 ) ;
1044
+ let err_end = Position :: new ( end_line - 1 , end_col - 1 ) ;
1045
+ let err_span = source_span:: Span :: new ( err_start, err_end, err_end. next_column ( ) ) ;
1046
+ fmt. add ( err_span, Some ( friendly_string. clone ( ) ) , style) ;
1047
+ }
873
1048
}
0 commit comments