mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-12 22:49:20 +02:00
fcl-passrc: $Writeableconst
git-svn-id: trunk@38872 -
This commit is contained in:
parent
b1b6b52842
commit
7db9ac914f
@ -169,6 +169,7 @@ const
|
|||||||
nTypeXIsNotYetCompletelyDefined = 3107;
|
nTypeXIsNotYetCompletelyDefined = 3107;
|
||||||
nDuplicateCaseValueXatY = 3108;
|
nDuplicateCaseValueXatY = 3108;
|
||||||
nMissingFieldsX = 3109;
|
nMissingFieldsX = 3109;
|
||||||
|
nCantAssignValuesToConstVariable = 3110;
|
||||||
|
|
||||||
// resourcestring patterns of messages
|
// resourcestring patterns of messages
|
||||||
resourcestring
|
resourcestring
|
||||||
@ -270,6 +271,7 @@ resourcestring
|
|||||||
sTypeXIsNotYetCompletelyDefined = 'type "%s" is not yet completely defined';
|
sTypeXIsNotYetCompletelyDefined = 'type "%s" is not yet completely defined';
|
||||||
sDuplicateCaseValueXatY = 'Duplicate case value "%s", other at %s';
|
sDuplicateCaseValueXatY = 'Duplicate case value "%s", other at %s';
|
||||||
sMissingFieldsX = 'Missing fields: "%s"';
|
sMissingFieldsX = 'Missing fields: "%s"';
|
||||||
|
sCantAssignValuesToConstVariable = 'Can''t assign values to const variable';
|
||||||
|
|
||||||
type
|
type
|
||||||
{ TResolveData - base class for data stored in TPasElement.CustomData }
|
{ TResolveData - base class for data stored in TPasElement.CustomData }
|
||||||
|
@ -148,6 +148,7 @@ Works:
|
|||||||
- TypedPointer:=@Some
|
- TypedPointer:=@Some
|
||||||
- pointer[index], (@i)[index]
|
- pointer[index], (@i)[index]
|
||||||
- dispose(pointerofrecord), new(pointerofrecord)
|
- dispose(pointerofrecord), new(pointerofrecord)
|
||||||
|
- $PointerMath on|off
|
||||||
- emit hints
|
- emit hints
|
||||||
- platform, deprecated, experimental, library, unimplemented
|
- platform, deprecated, experimental, library, unimplemented
|
||||||
- hiding ancestor method
|
- hiding ancestor method
|
||||||
@ -201,13 +202,12 @@ Works:
|
|||||||
- eval +, -, *, /, ^^
|
- eval +, -, *, /, ^^
|
||||||
- float*currency and currency*float computes to currency
|
- float*currency and currency*float computes to currency
|
||||||
- type alias type overloads
|
- type alias type overloads
|
||||||
|
- $writeableconst off $J-
|
||||||
|
|
||||||
ToDo:
|
ToDo:
|
||||||
- $pop, $push
|
- $pop, $push
|
||||||
- $writableconst off $J-
|
|
||||||
- $RTTI inherited|explicit
|
- $RTTI inherited|explicit
|
||||||
- range checking:
|
- range checking:
|
||||||
- indexedprop[param]
|
|
||||||
- defaultvalue
|
- defaultvalue
|
||||||
- fail to write a loop var inside the loop
|
- fail to write a loop var inside the loop
|
||||||
- nested classes
|
- nested classes
|
||||||
@ -14995,6 +14995,8 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
if ResolvedEl.IdentEl is TPasProperty then
|
if ResolvedEl.IdentEl is TPasProperty then
|
||||||
RaiseMsg(20170216152427,nPropertyNotWritable,sPropertyNotWritable,[],ErrorEl)
|
RaiseMsg(20170216152427,nPropertyNotWritable,sPropertyNotWritable,[],ErrorEl)
|
||||||
|
else if ResolvedEl.IdentEl is TPasConst then
|
||||||
|
RaiseMsg(20180430012042,nCantAssignValuesToConstVariable,sCantAssignValuesToConstVariable,[],ErrorEl)
|
||||||
else
|
else
|
||||||
RaiseMsg(20170216152429,nVariableIdentifierExpected,sVariableIdentifierExpected,[],ErrorEl);
|
RaiseMsg(20170216152429,nVariableIdentifierExpected,sVariableIdentifierExpected,[],ErrorEl);
|
||||||
end;
|
end;
|
||||||
@ -16485,7 +16487,12 @@ begin
|
|||||||
writeln('TPasResolver.CheckParamCompatibility NeedWritable: ',GetResolverResultDbg(ExprResolved));
|
writeln('TPasResolver.CheckParamCompatibility NeedWritable: ',GetResolverResultDbg(ExprResolved));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
if RaiseOnError then
|
if RaiseOnError then
|
||||||
RaiseMsg(20170216152450,nVariableIdentifierExpected,sVariableIdentifierExpected,[],Expr);
|
begin
|
||||||
|
if ExprResolved.IdentEl is TPasConst then
|
||||||
|
RaiseMsg(20180430012609,nCantAssignValuesToConstVariable,sCantAssignValuesToConstVariable,[],Expr)
|
||||||
|
else
|
||||||
|
RaiseMsg(20180430012457,nVariableIdentifierExpected,sVariableIdentifierExpected,[],Expr);
|
||||||
|
end;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
if (ParamResolved.BaseType=ExprResolved.BaseType) then
|
if (ParamResolved.BaseType=ExprResolved.BaseType) then
|
||||||
@ -17871,12 +17878,15 @@ begin
|
|||||||
// e.g. 'var a:b' -> compute b, use a as IdentEl
|
// e.g. 'var a:b' -> compute b, use a as IdentEl
|
||||||
if TPasConst(El).VarType<>nil then
|
if TPasConst(El).VarType<>nil then
|
||||||
begin
|
begin
|
||||||
// typed const -> just like a var
|
// typed const
|
||||||
if rcConstant in Flags then
|
if (not TPasConst(El).IsConst) and ([rcConstant,rcType]*Flags<>[]) then
|
||||||
RaiseConstantExprExp(20170216152739,StartEl);
|
RaiseConstantExprExp(20170216152739,StartEl);
|
||||||
ComputeElement(TPasConst(El).VarType,ResolvedEl,Flags+[rcType],StartEl);
|
ComputeElement(TPasConst(El).VarType,ResolvedEl,Flags+[rcType],StartEl);
|
||||||
ResolvedEl.IdentEl:=El;
|
ResolvedEl.IdentEl:=El;
|
||||||
ResolvedEl.Flags:=[rrfReadable,rrfWritable];
|
if TPasConst(El).IsConst then
|
||||||
|
ResolvedEl.Flags:=[rrfReadable]
|
||||||
|
else
|
||||||
|
ResolvedEl.Flags:=[rrfReadable,rrfWritable];
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
@ -3649,6 +3649,8 @@ begin
|
|||||||
NextToken;
|
NextToken;
|
||||||
if CurToken = tkColon then
|
if CurToken = tkColon then
|
||||||
begin
|
begin
|
||||||
|
if not (bsWriteableConst in Scanner.CurrentBoolSwitches) then
|
||||||
|
Result.IsConst:=true;
|
||||||
OldForceCaret:=Scanner.SetForceCaret(True);
|
OldForceCaret:=Scanner.SetForceCaret(True);
|
||||||
try
|
try
|
||||||
Result.VarType := ParseType(Result,CurSourcePos);
|
Result.VarType := ParseType(Result,CurSourcePos);
|
||||||
|
@ -337,11 +337,11 @@ const
|
|||||||
);
|
);
|
||||||
|
|
||||||
bsAll = [low(TBoolSwitch)..high(TBoolSwitch)];
|
bsAll = [low(TBoolSwitch)..high(TBoolSwitch)];
|
||||||
bsFPCMode: TBoolSwitches = [bsPointerMath];
|
bsFPCMode: TBoolSwitches = [bsPointerMath,bsWriteableConst];
|
||||||
bsObjFPCMode: TBoolSwitches = [bsPointerMath];
|
bsObjFPCMode: TBoolSwitches = [bsPointerMath,bsWriteableConst];
|
||||||
bsDelphiMode: TBoolSwitches = [];
|
bsDelphiMode: TBoolSwitches = [bsWriteableConst];
|
||||||
bsDelphiUnicodeMode: TBoolSwitches = [];
|
bsDelphiUnicodeMode: TBoolSwitches = [bsWriteableConst];
|
||||||
bsMacPasMode: TBoolSwitches = [bsPointerMath];
|
bsMacPasMode: TBoolSwitches = [bsPointerMath,bsWriteableConst];
|
||||||
|
|
||||||
type
|
type
|
||||||
TValueSwitch = (
|
TValueSwitch = (
|
||||||
@ -3150,6 +3150,8 @@ begin
|
|||||||
Result:=HandleInclude(Param);
|
Result:=HandleInclude(Param);
|
||||||
'INTERFACES':
|
'INTERFACES':
|
||||||
HandleInterfaces(Param);
|
HandleInterfaces(Param);
|
||||||
|
'LONGSTRINGS':
|
||||||
|
DoBoolDirective(bsLongStrings);
|
||||||
'MACRO':
|
'MACRO':
|
||||||
DoBoolDirective(bsMacro);
|
DoBoolDirective(bsMacro);
|
||||||
'MESSAGE':
|
'MESSAGE':
|
||||||
@ -3162,8 +3164,16 @@ begin
|
|||||||
DoLog(mtNote,nUserDefined,SUserDefined,[Param]);
|
DoLog(mtNote,nUserDefined,SUserDefined,[Param]);
|
||||||
'NOTES':
|
'NOTES':
|
||||||
DoBoolDirective(bsNotes);
|
DoBoolDirective(bsNotes);
|
||||||
|
'OBJECTCHECKS':
|
||||||
|
DoBoolDirective(bsObjectChecks);
|
||||||
|
'POINTERMATH':
|
||||||
|
DoBoolDirective(bsPointerMath);
|
||||||
|
'RANGECHECKS':
|
||||||
|
DoBoolDirective(bsRangeChecks);
|
||||||
'SCOPEDENUMS':
|
'SCOPEDENUMS':
|
||||||
DoBoolDirective(bsScopedEnums);
|
DoBoolDirective(bsScopedEnums);
|
||||||
|
'TYPEDADDRESS':
|
||||||
|
DoBoolDirective(bsTypedAddress);
|
||||||
'TYPEINFO':
|
'TYPEINFO':
|
||||||
DoBoolDirective(bsTypeInfo);
|
DoBoolDirective(bsTypeInfo);
|
||||||
'UNDEF':
|
'UNDEF':
|
||||||
@ -3172,6 +3182,8 @@ begin
|
|||||||
DoLog(mtWarning,nUserDefined,SUserDefined,[Param]);
|
DoLog(mtWarning,nUserDefined,SUserDefined,[Param]);
|
||||||
'WARNINGS':
|
'WARNINGS':
|
||||||
DoBoolDirective(bsWarnings);
|
DoBoolDirective(bsWarnings);
|
||||||
|
'WRITEABLECONST':
|
||||||
|
DoBoolDirective(bsWriteableConst);
|
||||||
else
|
else
|
||||||
Handled:=false;
|
Handled:=false;
|
||||||
end;
|
end;
|
||||||
|
@ -207,6 +207,9 @@ type
|
|||||||
Procedure TestConstFloatOperators;
|
Procedure TestConstFloatOperators;
|
||||||
Procedure TestFloatTypeCast;
|
Procedure TestFloatTypeCast;
|
||||||
Procedure TestCurrency;
|
Procedure TestCurrency;
|
||||||
|
Procedure TestWritableConst;
|
||||||
|
Procedure TestWritableConst_AssignFail;
|
||||||
|
Procedure TestWritableConst_PassVarFail;
|
||||||
|
|
||||||
// boolean
|
// boolean
|
||||||
Procedure TestBoolTypeCast;
|
Procedure TestBoolTypeCast;
|
||||||
@ -2646,6 +2649,42 @@ begin
|
|||||||
CheckResolverUnexpectedHints;
|
CheckResolverUnexpectedHints;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolver.TestWritableConst;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'{$writeableconst off}',
|
||||||
|
'const i: longint = 3;',
|
||||||
|
'begin',
|
||||||
|
'']);
|
||||||
|
ParseProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolver.TestWritableConst_AssignFail;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'{$writeableconst off}',
|
||||||
|
'const i: longint = 3;',
|
||||||
|
'begin',
|
||||||
|
' i:=4;',
|
||||||
|
'']);
|
||||||
|
CheckResolverException(sCantAssignValuesToConstVariable,nCantAssignValuesToConstVariable);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolver.TestWritableConst_PassVarFail;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'{$writeableconst off}',
|
||||||
|
'const i: longint = 3;',
|
||||||
|
'procedure DoIt(var j: longint); external;',
|
||||||
|
'begin',
|
||||||
|
' DoIt(i);',
|
||||||
|
'']);
|
||||||
|
CheckResolverException(sCantAssignValuesToConstVariable,nCantAssignValuesToConstVariable);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestResolver.TestBoolTypeCast;
|
procedure TTestResolver.TestBoolTypeCast;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
@ -343,7 +343,7 @@ Works:
|
|||||||
|
|
||||||
ToDos:
|
ToDos:
|
||||||
- option typecast checking -Ct
|
- option typecast checking -Ct
|
||||||
- writable const
|
- $writableconst
|
||||||
- 'new', 'Function' -> class var use .prototype
|
- 'new', 'Function' -> class var use .prototype
|
||||||
- btArrayLit
|
- btArrayLit
|
||||||
a: array of jsvalue;
|
a: array of jsvalue;
|
||||||
@ -391,13 +391,14 @@ Not in Version 1.0:
|
|||||||
- set operators on literals without temporary arrays, a in [b], [a]*b<>[]
|
- set operators on literals without temporary arrays, a in [b], [a]*b<>[]
|
||||||
- nested procs without var, instead as "function name(){}"
|
- nested procs without var, instead as "function name(){}"
|
||||||
- combine multiple var a=0,b=0
|
- combine multiple var a=0,b=0
|
||||||
|
- skip clone record for new record
|
||||||
|
- SetLength(scope.a,l) -> read scope only once, same for
|
||||||
|
Include, Exclude, Inc, Dec, +=, -=, *=, /=
|
||||||
-O1 insert local/unit vars for global type references:
|
-O1 insert local/unit vars for global type references:
|
||||||
at start of intf var $r1;
|
at start of intf var $r1;
|
||||||
at end of impl: $r1=path;
|
at end of impl: $r1=path;
|
||||||
-O1 insert unit vars for complex literals
|
-O1 insert unit vars for complex literals
|
||||||
-O1 no function Result var when assigned only once
|
-O1 no function Result var when assigned only once
|
||||||
- SetLength(scope.a,l) -> read scope only once, same for
|
|
||||||
Include, Exclude, Inc, Dec, +=, -=, *=, /=
|
|
||||||
-O1 replace constant expression with result
|
-O1 replace constant expression with result
|
||||||
-O1 pass array element by ref: when index is constant, use that directly
|
-O1 pass array element by ref: when index is constant, use that directly
|
||||||
- objects
|
- objects
|
||||||
@ -1031,6 +1032,7 @@ const
|
|||||||
msAllPas2jsBoolSwitches = [
|
msAllPas2jsBoolSwitches = [
|
||||||
bsAssertions,
|
bsAssertions,
|
||||||
bsRangeChecks,
|
bsRangeChecks,
|
||||||
|
bsWriteableConst,
|
||||||
bsTypeInfo,
|
bsTypeInfo,
|
||||||
bsOverflowChecks,
|
bsOverflowChecks,
|
||||||
bsHints,
|
bsHints,
|
||||||
|
@ -767,7 +767,7 @@ function TPas2jsCompilerFile.GetInitialBoolSwitches: TBoolSwitches;
|
|||||||
var
|
var
|
||||||
bs: TBoolSwitches;
|
bs: TBoolSwitches;
|
||||||
begin
|
begin
|
||||||
bs:=[];
|
bs:=[bsWriteableConst];
|
||||||
if coOverflowChecks in Compiler.Options then
|
if coOverflowChecks in Compiler.Options then
|
||||||
Include(bs,bsOverflowChecks);
|
Include(bs,bsOverflowChecks);
|
||||||
if coRangeChecks in Compiler.Options then
|
if coRangeChecks in Compiler.Options then
|
||||||
|
@ -1038,7 +1038,7 @@ begin
|
|||||||
aScanner.CurrentModeSwitches:=OBJFPCModeSwitches*msAllPas2jsModeSwitches+msAllPas2jsModeSwitchesReadOnly;
|
aScanner.CurrentModeSwitches:=OBJFPCModeSwitches*msAllPas2jsModeSwitches+msAllPas2jsModeSwitchesReadOnly;
|
||||||
|
|
||||||
aScanner.AllowedBoolSwitches:=msAllPas2jsBoolSwitches;
|
aScanner.AllowedBoolSwitches:=msAllPas2jsBoolSwitches;
|
||||||
aScanner.CurrentBoolSwitches:=[bsHints,bsNotes,bsWarnings];
|
aScanner.CurrentBoolSwitches:=[bsHints,bsNotes,bsWarnings,bsWriteableConst];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomTestModule.TearDown;
|
procedure TCustomTestModule.TearDown;
|
||||||
|
Loading…
Reference in New Issue
Block a user