MG: expression type of string brackets

git-svn-id: trunk@648 -
This commit is contained in:
lazarus 2002-01-30 21:48:33 +00:00
parent 6f4f1d0688
commit abc995925d

View File

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