mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 18:47:52 +02:00
fcl-passrc: resolver+useanalyzer: implemented resourcestring
git-svn-id: trunk@37392 -
This commit is contained in:
parent
48024645f0
commit
203c723bc3
@ -982,6 +982,7 @@ type
|
||||
procedure AddRecordType(El: TPasRecordType); virtual;
|
||||
procedure AddClassType(El: TPasClassType); virtual;
|
||||
procedure AddVariable(El: TPasVariable); virtual;
|
||||
procedure AddResourceString(El: TPasResString); virtual;
|
||||
procedure AddEnumType(El: TPasEnumType); virtual;
|
||||
procedure AddEnumValue(El: TPasEnumValue); virtual;
|
||||
procedure AddProperty(El: TPasProperty); virtual;
|
||||
@ -1035,6 +1036,7 @@ type
|
||||
procedure FinishClassOfType(El: TPasClassOfType); virtual;
|
||||
procedure FinishArrayType(El: TPasArrayType); virtual;
|
||||
procedure FinishConstDef(El: TPasConst); virtual;
|
||||
procedure FinishResourcestring(El: TPasResString); virtual;
|
||||
procedure FinishProcedure(aProc: TPasProcedure); virtual;
|
||||
procedure FinishProcedureType(El: TPasProcedureType); virtual;
|
||||
procedure FinishMethodDeclHeader(Proc: TPasProcedure); virtual;
|
||||
@ -3484,6 +3486,16 @@ begin
|
||||
Eval(El.Expr,[refConst])
|
||||
end;
|
||||
|
||||
procedure TPasResolver.FinishResourcestring(El: TPasResString);
|
||||
var
|
||||
ResolvedEl: TPasResolverResult;
|
||||
begin
|
||||
ResolveExpr(El.Expr,rraRead);
|
||||
ComputeElement(El.Expr,ResolvedEl,[rcConstant]);
|
||||
if not (ResolvedEl.BaseType in btAllStringAndChars) then
|
||||
RaiseXExpectedButYFound(20171004135753,'string',GetTypeDescription(ResolvedEl),El.Expr);
|
||||
end;
|
||||
|
||||
procedure TPasResolver.FinishProcedure(aProc: TPasProcedure);
|
||||
var
|
||||
i: Integer;
|
||||
@ -6159,6 +6171,21 @@ begin
|
||||
AddIdentifier(TPasIdentifierScope(TopScope),El.Name,El,pikSimple);
|
||||
end;
|
||||
|
||||
procedure TPasResolver.AddResourceString(El: TPasResString);
|
||||
var
|
||||
C: TClass;
|
||||
begin
|
||||
{$IFDEF VerbosePasResolver}
|
||||
writeln('TPasResolver.AddResourceString ',GetObjName(El));
|
||||
{$ENDIF}
|
||||
if not (TopScope is TPasIdentifierScope) then
|
||||
RaiseInvalidScopeForElement(20171004092114,El);
|
||||
C:=El.Parent.ClassType;
|
||||
if not C.InheritsFrom(TPasSection) then
|
||||
RaiseNotYetImplemented(20171004092518,El);
|
||||
AddIdentifier(TPasIdentifierScope(TopScope),El.Name,El,pikSimple);
|
||||
end;
|
||||
|
||||
procedure TPasResolver.AddEnumType(El: TPasEnumType);
|
||||
var
|
||||
CanonicalSet: TPasSetType;
|
||||
@ -9383,6 +9410,8 @@ begin
|
||||
if (AClass=TPasVariable)
|
||||
or (AClass=TPasConst) then
|
||||
AddVariable(TPasVariable(El))
|
||||
else if AClass=TPasResString then
|
||||
AddResourceString(TPasResString(El))
|
||||
else if (AClass=TPasProperty) then
|
||||
AddProperty(TPasProperty(El))
|
||||
else if AClass=TPasArgument then
|
||||
@ -9435,7 +9464,7 @@ begin
|
||||
else if AClass.InheritsFrom(TPasExpr) then
|
||||
// resolved when finished
|
||||
else if AClass.InheritsFrom(TPasImplBlock) then
|
||||
// resolved finished
|
||||
// resolved when finished
|
||||
else
|
||||
RaiseNotYetImplemented(20160922163544,El);
|
||||
end;
|
||||
@ -13447,6 +13476,8 @@ begin
|
||||
if BaseTypes[btShortString]=nil then
|
||||
RaiseMsg(20170419203146,nIllegalQualifier,sIllegalQualifier,['['],El);
|
||||
end
|
||||
else if ElClass=TPasResString then
|
||||
SetResolverIdentifier(ResolvedEl,btString,El,nil,[rrfReadable])
|
||||
else
|
||||
RaiseNotYetImplemented(20160922163705,El);
|
||||
end;
|
||||
|
@ -205,6 +205,7 @@ type
|
||||
procedure UseClassType(El: TPasClassType; Mode: TPAUseMode); virtual;
|
||||
procedure UseVariable(El: TPasVariable; Access: TResolvedRefAccess;
|
||||
UseFull: boolean); virtual;
|
||||
procedure UseResourcestring(El: TPasResString); virtual;
|
||||
procedure UseArgument(El: TPasArgument; Access: TResolvedRefAccess); virtual;
|
||||
procedure UseResultElement(El: TPasResultElement; Access: TResolvedRefAccess); virtual;
|
||||
// create hints for a unit, program or library
|
||||
@ -607,6 +608,8 @@ begin
|
||||
UseArgument(TPasArgument(El),Access)
|
||||
else if C=TPasResultElement then
|
||||
UseResultElement(TPasResultElement(El),Access)
|
||||
else if C=TPasResString then
|
||||
UseResourcestring(TPasResString(El))
|
||||
else if C.InheritsFrom(TPasProcedure) then
|
||||
UseProcedure(TPasProcedure(El))
|
||||
else if C.InheritsFrom(TPasExpr) then
|
||||
@ -753,6 +756,7 @@ var
|
||||
Decl: TPasElement;
|
||||
OnlyExports: Boolean;
|
||||
UsesClause: TPasUsesClause;
|
||||
C: TClass;
|
||||
begin
|
||||
// Section is TProgramSection, TLibrarySection, TInterfaceSection, TImplementationSection
|
||||
if Mode=paumElement then
|
||||
@ -798,20 +802,23 @@ begin
|
||||
{$IFDEF VerbosePasAnalyzer}
|
||||
writeln('TPasAnalyzer.UseSection ',Section.ClassName,' Decl=',GetElModName(Decl),' Mode=',Mode);
|
||||
{$ENDIF}
|
||||
if Decl is TPasProcedure then
|
||||
C:=Decl.ClassType;
|
||||
if C.InheritsFrom(TPasProcedure) then
|
||||
begin
|
||||
if OnlyExports and ([pmExport,pmPublic]*TPasProcedure(Decl).Modifiers=[]) then
|
||||
continue;
|
||||
UseProcedure(TPasProcedure(Decl))
|
||||
end
|
||||
else if Decl is TPasType then
|
||||
else if C.InheritsFrom(TPasType) then
|
||||
UseType(TPasType(Decl),Mode)
|
||||
else if Decl is TPasVariable then
|
||||
else if C.InheritsFrom(TPasVariable) then
|
||||
begin
|
||||
if OnlyExports and ([vmExport,vmPublic]*TPasVariable(Decl).VarModifiers=[]) then
|
||||
continue;
|
||||
UseVariable(TPasVariable(Decl),rraNone,true);
|
||||
end
|
||||
else if C=TPasResString then
|
||||
UseResourcestring(TPasResString(Decl))
|
||||
else
|
||||
RaiseNotSupported(20170306165213,Decl);
|
||||
end;
|
||||
@ -1491,6 +1498,12 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPasAnalyzer.UseResourcestring(El: TPasResString);
|
||||
begin
|
||||
if MarkElementAsUsed(El) then
|
||||
UseExpr(El.Expr);
|
||||
end;
|
||||
|
||||
procedure TPasAnalyzer.UseArgument(El: TPasArgument; Access: TResolvedRefAccess
|
||||
);
|
||||
var
|
||||
|
@ -78,6 +78,7 @@ const
|
||||
nParserExpectedExternalClassName = 2051;
|
||||
nParserNoConstRangeAllowed = 2052;
|
||||
nErrRecordVariablesNotAllowed = 2053;
|
||||
nParserResourcestringsMustBeGlobal = 2054;
|
||||
|
||||
// resourcestring patterns of messages
|
||||
resourcestring
|
||||
@ -134,6 +135,7 @@ resourcestring
|
||||
SParserPropertyArgumentsCanNotHaveDefaultValues = 'Property arguments can not have default values';
|
||||
SParserExpectedExternalClassName = 'Expected external class name';
|
||||
SParserNoConstRangeAllowed = 'Const ranges are not allowed';
|
||||
SParserResourcestringsMustBeGlobal = 'Resourcestrings can be only static or global';
|
||||
|
||||
type
|
||||
TPasScopeType = (
|
||||
@ -2998,7 +3000,15 @@ begin
|
||||
tkexports:
|
||||
SetBlock(declExports);
|
||||
tkResourcestring:
|
||||
SetBlock(declResourcestring);
|
||||
if Declarations is TPasSection then
|
||||
SetBlock(declResourcestring)
|
||||
else
|
||||
begin
|
||||
{ $IFDEF VerbosePasParser}
|
||||
writeln('TPasParser.ParseDeclarations ',Declarations.Parent.ClassName);
|
||||
{ $ENDIF}
|
||||
ParseExc(nParserResourcestringsMustBeGlobal,SParserResourcestringsMustBeGlobal);
|
||||
end;
|
||||
tkType:
|
||||
SetBlock(declType);
|
||||
tkVar:
|
||||
|
@ -619,6 +619,13 @@ type
|
||||
Procedure TestPointer_TypecastMethod_proMethodAddrAsPointer;
|
||||
Procedure TestPointer_OverloadSignature;
|
||||
|
||||
// resourcestrings
|
||||
Procedure TestResourcestring;
|
||||
Procedure TestResourcestringAssignFail;
|
||||
Procedure TestResourcestringLocalFail;
|
||||
Procedure TestResourcestringInConstFail;
|
||||
Procedure TestResourcestringPassVarArgFail;
|
||||
|
||||
// hints
|
||||
Procedure TestHint_ElementHints;
|
||||
Procedure TestHint_ElementHintsMsg;
|
||||
@ -10397,6 +10404,70 @@ begin
|
||||
ParseProgram;
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestResourcestring;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'const Foo = ''foo'';',
|
||||
'Resourcestring',
|
||||
' Bar = foo;',
|
||||
' Red = ''Red'';',
|
||||
' r = ''Rd''+foo;',
|
||||
'procedure DoIt(s: string; const h: string); begin end;',
|
||||
'begin',
|
||||
' if bar=red then ;',
|
||||
' if bar=''a'' then ;',
|
||||
' doit(r,r);',
|
||||
'']);
|
||||
ParseProgram;
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestResourcestringAssignFail;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'Resourcestring Foo = ''bar'';',
|
||||
'begin',
|
||||
' Foo:=''a'';',
|
||||
'']);
|
||||
CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestResourcestringLocalFail;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'procedure DoIt;',
|
||||
'Resourcestring Foo = ''bar'';',
|
||||
'begin end;',
|
||||
'begin;',
|
||||
'']);
|
||||
CheckParserException(SParserResourcestringsMustBeGlobal,nParserResourcestringsMustBeGlobal);
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestResourcestringInConstFail;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'Resourcestring Foo = ''foo'';',
|
||||
'const Bar = ''Prefix''+Foo;',
|
||||
'begin',
|
||||
'']);
|
||||
CheckResolverException(sConstantExpressionExpected,nConstantExpressionExpected);
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestResourcestringPassVarArgFail;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add([
|
||||
'Resourcestring Bar = ''foo'';',
|
||||
'procedure DoIt(var s: string); begin end;',
|
||||
'begin',
|
||||
' doit(bar);',
|
||||
'']);
|
||||
CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestHint_ElementHints;
|
||||
begin
|
||||
StartProgram(false);
|
||||
|
@ -545,6 +545,7 @@ end;
|
||||
procedure TTestUseAnalyzer.TestM_Const;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add('resourcestring {#rs_used}rs = ''txt'';');
|
||||
Add('procedure {#DoIt_used}DoIt;');
|
||||
Add('var');
|
||||
Add(' {#a_used}a: longint;');
|
||||
@ -555,7 +556,7 @@ begin
|
||||
Add(' a:=+1;');
|
||||
Add(' b:=true;');
|
||||
Add(' c:=nil;');
|
||||
Add(' d:=''foo'';');
|
||||
Add(' d:=''foo''+rs;');
|
||||
Add('end;');
|
||||
Add('begin');
|
||||
Add(' DoIt;');
|
||||
|
Loading…
Reference in New Issue
Block a user