mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 06:59:14 +02:00
MG: expression type of string brackets
git-svn-id: trunk@648 -
This commit is contained in:
parent
6f4f1d0688
commit
abc995925d
@ -87,7 +87,7 @@ interface
|
|||||||
{ $DEFINE CTDEBUG}
|
{ $DEFINE CTDEBUG}
|
||||||
{ $DEFINE ShowTriedFiles}
|
{ $DEFINE ShowTriedFiles}
|
||||||
{ $DEFINE ShowTriedContexts}
|
{ $DEFINE ShowTriedContexts}
|
||||||
{ $DEFINE ShowExprEval}
|
{$DEFINE ShowExprEval}
|
||||||
{ $DEFINE ShowFoundIdentifier}
|
{ $DEFINE ShowFoundIdentifier}
|
||||||
{ $DEFINE ShowCachedIdentifiers}
|
{ $DEFINE ShowCachedIdentifiers}
|
||||||
|
|
||||||
@ -122,7 +122,10 @@ type
|
|||||||
fdfIgnoreMissingParams, // found proc fits, even if parameters are missing
|
fdfIgnoreMissingParams, // found proc fits, even if parameters are missing
|
||||||
fdfFirstIdentFound, // a first identifier was found, now searching for
|
fdfFirstIdentFound, // a first identifier was found, now searching for
|
||||||
// the a better one (used for proc overloading)
|
// the a better one (used for proc overloading)
|
||||||
fdfOnlyCompatibleProc // incompatible procs are ignored
|
fdfOnlyCompatibleProc, // incompatible procs are ignored
|
||||||
|
fdfNoExceptionOnStringChar// the bracket operator after a predefined string
|
||||||
|
// is of type char, which is also predefined, so it
|
||||||
|
// can not be resolved normally
|
||||||
);
|
);
|
||||||
TFindDeclarationFlags = set of TFindDeclarationFlag;
|
TFindDeclarationFlags = set of TFindDeclarationFlag;
|
||||||
|
|
||||||
@ -145,7 +148,7 @@ type
|
|||||||
xtExtended, xtCurrency, xtComp, xtInt64, xtCardinal, xtQWord, xtBoolean,
|
xtExtended, xtCurrency, xtComp, xtInt64, xtCardinal, xtQWord, xtBoolean,
|
||||||
xtByteBool, xtLongBool, xtString, xtAnsiString, xtShortString, xtWideString,
|
xtByteBool, xtLongBool, xtString, xtAnsiString, xtShortString, xtWideString,
|
||||||
xtPChar, xtPointer, xtConstOrdInteger, xtConstString, xtConstReal,
|
xtPChar, xtPointer, xtConstOrdInteger, xtConstString, xtConstReal,
|
||||||
xtConstSet, xtConstBoolean, xtNil);
|
xtConstSet, xtConstBoolean, xtAddress, xtNil);
|
||||||
TExpressionTypeDescs = set of TExpressionTypeDesc;
|
TExpressionTypeDescs = set of TExpressionTypeDesc;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -154,7 +157,7 @@ const
|
|||||||
'Extended', 'Currency', 'Comp', 'Int64', 'Cardinal', 'QWord', 'Boolean',
|
'Extended', 'Currency', 'Comp', 'Int64', 'Cardinal', 'QWord', 'Boolean',
|
||||||
'ByteBool', 'LongBool', 'String', 'AnsiString', 'ShortString', 'WideString',
|
'ByteBool', 'LongBool', 'String', 'AnsiString', 'ShortString', 'WideString',
|
||||||
'PChar', 'Pointer', 'ConstOrdInt', 'ConstString', 'ConstReal', 'ConstSet',
|
'PChar', 'Pointer', 'ConstOrdInt', 'ConstString', 'ConstReal', 'ConstSet',
|
||||||
'ConstBoolean', 'Nil'
|
'ConstBoolean', '@-Operator', 'Nil'
|
||||||
);
|
);
|
||||||
|
|
||||||
xtAllTypes = [xtContext..High(TExpressionTypeDesc)];
|
xtAllTypes = [xtContext..High(TExpressionTypeDesc)];
|
||||||
@ -169,7 +172,7 @@ const
|
|||||||
xtAllRealConvertibles = xtAllRealTypes+xtAllIntegerTypes;
|
xtAllRealConvertibles = xtAllRealTypes+xtAllIntegerTypes;
|
||||||
xtAllStringConvertibles = xtAllStringTypes+[xtChar,xtPChar];
|
xtAllStringConvertibles = xtAllStringTypes+[xtChar,xtPChar];
|
||||||
xtAllBooleanConvertibles = xtAllBooleanTypes+[xtConstBoolean];
|
xtAllBooleanConvertibles = xtAllBooleanTypes+[xtConstBoolean];
|
||||||
xtAllPointerConvertibles = xtAllPointerTypes+[xtPChar];
|
xtAllPointerConvertibles = xtAllPointerTypes+[xtPChar,xtAddress];
|
||||||
|
|
||||||
type
|
type
|
||||||
{ TExpressionType is used for compatibility check
|
{ TExpressionType is used for compatibility check
|
||||||
@ -327,8 +330,6 @@ type
|
|||||||
function FindIdentifierInUsedUnit(const AnUnitName: string;
|
function FindIdentifierInUsedUnit(const AnUnitName: string;
|
||||||
Params: TFindDeclarationParams): boolean;
|
Params: TFindDeclarationParams): boolean;
|
||||||
function FindEndOfVariable(StartPos: integer): integer;
|
function FindEndOfVariable(StartPos: integer): integer;
|
||||||
function FindTypeOfVariable(StartPos: integer;
|
|
||||||
Params: TFindDeclarationParams; var EndPos: integer): TFindContext;
|
|
||||||
function FindExpressionTypeOfVariable(StartPos: integer;
|
function FindExpressionTypeOfVariable(StartPos: integer;
|
||||||
Params: TFindDeclarationParams; var EndPos: integer): TExpressionType;
|
Params: TFindDeclarationParams; var EndPos: integer): TExpressionType;
|
||||||
function ConvertNodeToExpressionType(Node: TCodeTreeNode;
|
function ConvertNodeToExpressionType(Node: TCodeTreeNode;
|
||||||
@ -1458,7 +1459,6 @@ writeln('');
|
|||||||
+(fdfGlobals*Params.Flags);
|
+(fdfGlobals*Params.Flags);
|
||||||
if CurAtomType=atPreDefIdentifier then
|
if CurAtomType=atPreDefIdentifier then
|
||||||
Exclude(Params.Flags,fdfExceptionOnNotFound);
|
Exclude(Params.Flags,fdfExceptionOnNotFound);
|
||||||
//writeln(' AAA ',Result.Node=Params.ContextNode,' ',Result.Node.DescAsString,',',Params.ContextNode.DescAsString);
|
|
||||||
if Result.Node=Params.ContextNode then begin
|
if Result.Node=Params.ContextNode then begin
|
||||||
// there is no special context -> also search in parent contexts
|
// there is no special context -> also search in parent contexts
|
||||||
Params.Flags:=Params.Flags
|
Params.Flags:=Params.Flags
|
||||||
@ -1552,12 +1552,14 @@ writeln('');
|
|||||||
|
|
||||||
atEdgedBracketClose:
|
atEdgedBracketClose:
|
||||||
begin
|
begin
|
||||||
// for example: a[]
|
{ for example: a[]
|
||||||
// this could be:
|
this could be:
|
||||||
// 1. ranged array
|
1. ranged array
|
||||||
// 2. dynamic array
|
2. dynamic array
|
||||||
// 3. indexed pointer
|
3. indexed pointer
|
||||||
// 4. default property
|
4. default property
|
||||||
|
5. string character
|
||||||
|
}
|
||||||
if not (NextAtomType in [atSpace,atPoint,atAs,atUp,atRoundBracketClose,
|
if not (NextAtomType in [atSpace,atPoint,atAs,atUp,atRoundBracketClose,
|
||||||
atRoundBracketOpen,atEdgedBracketClose,atEdgedBracketOpen]) then
|
atRoundBracketOpen,atEdgedBracketClose,atEdgedBracketOpen]) then
|
||||||
begin
|
begin
|
||||||
@ -1586,12 +1588,28 @@ writeln('');
|
|||||||
Params.SetIdentifier(Self,'[',nil);
|
Params.SetIdentifier(Self,'[',nil);
|
||||||
Params.ContextNode:=Result.Node;
|
Params.ContextNode:=Result.Node;
|
||||||
Result.Tool.FindIdentifierInContext(Params);
|
Result.Tool.FindIdentifierInContext(Params);
|
||||||
Result:=Params.NewCodeTool.FindBaseTypeOfNode(Params,Params.NewNode);
|
Result:=Params.NewCodeTool.FindBaseTypeOfNode(
|
||||||
|
Params,Params.NewNode);
|
||||||
Params.Load(OldInput);
|
Params.Load(OldInput);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
ctnIdentifier:
|
||||||
|
begin
|
||||||
|
MoveCursorToNodeStart(Result.Node);
|
||||||
|
ReadNextAtom;
|
||||||
|
if UpAtomIs('STRING') or UpAtomIs('ANSISTRING')
|
||||||
|
or UpAtomIs('SHORTSTRING') then begin
|
||||||
|
if not (fdfNoExceptionOnStringChar in Params.Flags) then begin
|
||||||
|
MoveCursorToCleanPos(CurAtom.StartPos);
|
||||||
|
ReadNextAtom;
|
||||||
|
RaiseException('illegal qualifier');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
else
|
else
|
||||||
MoveCursorToCleanPos(CurAtom.StartPos);
|
MoveCursorToCleanPos(CurAtom.StartPos);
|
||||||
|
ReadNextAtom;
|
||||||
RaiseException('illegal qualifier');
|
RaiseException('illegal qualifier');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2769,16 +2787,10 @@ begin
|
|||||||
break;
|
break;
|
||||||
until false;
|
until false;
|
||||||
if not AtomIsChar('.') then break;
|
if not AtomIsChar('.') then break;
|
||||||
|
ReadNextAtom;
|
||||||
until false;
|
until false;
|
||||||
Result:=CurPos.StartPos;
|
UndoReadNextAtom;
|
||||||
end;
|
Result:=CurPos.EndPos;
|
||||||
|
|
||||||
function TFindDeclarationTool.FindTypeOfVariable(StartPos: integer;
|
|
||||||
Params: TFindDeclarationParams; var EndPos: integer): TFindContext;
|
|
||||||
begin
|
|
||||||
EndPos:=FindEndOfVariable(StartPos);
|
|
||||||
MoveCursorToCleanPos(EndPos);
|
|
||||||
Result:=FindContextNodeAtCursor(Params);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFindDeclarationTool.FindExpressionTypeOfVariable(StartPos: integer;
|
function TFindDeclarationTool.FindExpressionTypeOfVariable(StartPos: integer;
|
||||||
@ -2786,6 +2798,7 @@ function TFindDeclarationTool.FindExpressionTypeOfVariable(StartPos: integer;
|
|||||||
var
|
var
|
||||||
OldInputFlags: TFindDeclarationFlags;
|
OldInputFlags: TFindDeclarationFlags;
|
||||||
IsPredefinedIdentifier: boolean;
|
IsPredefinedIdentifier: boolean;
|
||||||
|
CouldBeStringChar: boolean;
|
||||||
begin
|
begin
|
||||||
OldInputFlags:=Params.Flags;
|
OldInputFlags:=Params.Flags;
|
||||||
IsPredefinedIdentifier:=WordIsPredefinedIdentifier.DoIt(@Src[StartPos]);
|
IsPredefinedIdentifier:=WordIsPredefinedIdentifier.DoIt(@Src[StartPos]);
|
||||||
@ -2797,17 +2810,35 @@ writeln('[TFindDeclarationTool.FindExpressionTypeOfVariable] ',
|
|||||||
Exclude(Params.Flags,fdfExceptionOnNotFound)
|
Exclude(Params.Flags,fdfExceptionOnNotFound)
|
||||||
else
|
else
|
||||||
Include(Params.Flags,fdfExceptionOnNotFound);
|
Include(Params.Flags,fdfExceptionOnNotFound);
|
||||||
Result.Context:=FindTypeOfVariable(StartPos,Params,EndPos);
|
EndPos:=FindEndOfVariable(StartPos);
|
||||||
|
CouldBeStringChar:=AtomIsChar(']');
|
||||||
|
MoveCursorToCleanPos(EndPos);
|
||||||
|
Include(Params.Flags,fdfNoExceptionOnStringChar);
|
||||||
|
Result.Context:=FindContextNodeAtCursor(Params);
|
||||||
Params.Flags:=OldInputFlags;
|
Params.Flags:=OldInputFlags;
|
||||||
if Result.Context.Node=nil then begin
|
if Result.Context.Node<>nil then begin
|
||||||
|
if CouldBeStringChar then begin
|
||||||
|
CouldBeStringChar:=(Result.Context.Node.Desc=ctnIdentifier);
|
||||||
|
if CouldBeStringChar then begin
|
||||||
|
MoveCursorToNodeStart(Result.Context.Node);
|
||||||
|
ReadNextAtom;
|
||||||
|
CouldBeStringChar:=UpAtomIs('STRING') or UpAtomIs('ANSISTRING')
|
||||||
|
or UpAtomIs('SHORTSTRING');
|
||||||
|
if CouldBeStringChar then begin
|
||||||
|
Result.Context.Node:=nil;
|
||||||
|
Result.Desc:=xtChar;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:=Result.Context.Tool.ConvertNodeToExpressionType(Result.Context.Node,
|
||||||
|
Params);
|
||||||
|
end else begin
|
||||||
if IsPredefinedIdentifier then begin
|
if IsPredefinedIdentifier then begin
|
||||||
Result:=CleanExpressionType;
|
Result:=CleanExpressionType;
|
||||||
Result.Desc:=PredefinedIdentToTypeDesc(@Src[StartPos]);
|
Result.Desc:=PredefinedIdentToTypeDesc(@Src[StartPos]);
|
||||||
end else
|
end else
|
||||||
RaiseException('identifier expected, but '+GetAtom+' found');
|
RaiseException('identifier expected, but '+GetAtom+' found');
|
||||||
end else begin
|
|
||||||
Result:=Result.Context.Tool.ConvertNodeToExpressionType(Result.Context.Node,
|
|
||||||
Params);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3568,6 +3599,7 @@ writeln('[TFindDeclarationTool.IsCompatible] B ',
|
|||||||
' TargetType=',ExpressionTypeDescNames[TargetType.Desc],
|
' TargetType=',ExpressionTypeDescNames[TargetType.Desc],
|
||||||
' ExpressionType=',ExpressionTypeDescNames[ExpressionType.Desc]);
|
' ExpressionType=',ExpressionTypeDescNames[ExpressionType.Desc]);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
Result:=tcIncompatible;
|
||||||
if (TargetType.Desc=ExpressionType.Desc)
|
if (TargetType.Desc=ExpressionType.Desc)
|
||||||
and (not (TargetType.Desc in [xtNone,xtContext])) then begin
|
and (not (TargetType.Desc in [xtNone,xtContext])) then begin
|
||||||
Result:=tcExact;
|
Result:=tcExact;
|
||||||
|
Loading…
Reference in New Issue
Block a user