fcl-passrc: $Writeableconst

git-svn-id: trunk@38872 -
This commit is contained in:
Mattias Gaertner 2018-04-29 23:34:36 +00:00
parent b1b6b52842
commit 7db9ac914f
8 changed files with 83 additions and 16 deletions

View File

@ -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 }

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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;