codetools: resolve sub identifier in type definition: search forward too

git-svn-id: trunk@34720 -
This commit is contained in:
mattias 2012-01-12 23:12:01 +00:00
parent c91d3e41bf
commit 1c8d8b843e
2 changed files with 55 additions and 5 deletions

View File

@ -1983,7 +1983,7 @@ begin
// for example PMapID = ^TMapID // for example PMapID = ^TMapID
NewType:=TypeTool.ExtractCode(TypeNode.FirstChild.StartPos, NewType:=TypeTool.ExtractCode(TypeNode.FirstChild.StartPos,
TypeNode.FirstChild.EndPos,[]); TypeNode.FirstChild.EndPos,[]);
debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter pointer to ',NewType]); //debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter pointer to ',NewType]);
Params.Clear; Params.Clear;
Params.ContextNode:=TypeNode; Params.ContextNode:=TypeNode;
Params.Flags:=fdfDefaultForExpressions; Params.Flags:=fdfDefaultForExpressions;
@ -1991,7 +1991,7 @@ begin
ExprType:=TypeTool.FindExpressionResultType(Params, ExprType:=TypeTool.FindExpressionResultType(Params,
TypeNode.FirstChild.StartPos,TypeNode.FirstChild.EndPos, TypeNode.FirstChild.StartPos,TypeNode.FirstChild.EndPos,
@AliasType); @AliasType);
debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter parameter is pointer to type: AliasType=',FindContextToString(AliasType)]); //debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter parameter is pointer to type: AliasType=',FindContextToString(AliasType)]);
end; end;
end else begin end else begin
@ -2008,7 +2008,7 @@ begin
//debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter MissingUnitName=',MissingUnitName]); //debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter MissingUnitName=',MissingUnitName]);
end; end;
DebugLn('TCodeCompletionCodeTool.CompleteLocalVariableAsParameter NewType=',NewType); //DebugLn('TCodeCompletionCodeTool.CompleteLocalVariableAsParameter NewType=',NewType);
if NewType='' then if NewType='' then
RaiseException('CompleteLocalVariableAsParameter Internal error: NewType=""'); RaiseException('CompleteLocalVariableAsParameter Internal error: NewType=""');
end; end;

View File

@ -6698,6 +6698,7 @@ var
OldInput: TFindDeclarationInput; OldInput: TFindDeclarationInput;
StartFlags: TFindDeclarationFlags; StartFlags: TFindDeclarationFlags;
IsIdentEndOfVar: TIsIdentEndOfVar; IsIdentEndOfVar: TIsIdentEndOfVar;
FlagCanBeForwardDefined, FlagCanBeForwardDefinedValid: boolean;
ExprType: TExpressionType; ExprType: TExpressionType;
procedure RaiseIdentExpected; procedure RaiseIdentExpected;
@ -6767,6 +6768,7 @@ var
NextAtomType:=vatSpace; NextAtomType:=vatSpace;
MoveCursorToCleanPos(CurAtom.StartPos); MoveCursorToCleanPos(CurAtom.StartPos);
IsIdentEndOfVar:=iieovUnknown; IsIdentEndOfVar:=iieovUnknown;
FlagCanBeForwardDefinedValid:=false;
Result:=true; Result:=true;
end; end;
@ -6820,6 +6822,26 @@ var
end; end;
Result:=(IsIdentEndOfVar=iieovYes); Result:=(IsIdentEndOfVar=iieovYes);
end; end;
function CanBeForwardDefined: boolean;
var
Node: TCodeTreeNode;
begin
if not FlagCanBeForwardDefinedValid then begin
FlagCanBeForwardDefinedValid:=true;
FlagCanBeForwardDefined:=false;
Node:=StartNode;
while Node<>nil do begin
if Node.Desc in [ctnTypeDefinition,ctnGenericType] then begin
FlagCanBeForwardDefined:=true;
break;
end else if not (Node.Desc in AllPascalTypes) then
break;
Node:=Node.Parent;
end;
end;
Result:=FlagCanBeForwardDefined;
end;
procedure ResolveBaseTypeOfIdentifier; procedure ResolveBaseTypeOfIdentifier;
{ normally not the identifier is searched, but its type { normally not the identifier is searched, but its type
@ -6902,6 +6924,7 @@ var
IsStart: Boolean; IsStart: Boolean;
Context: TFindContext; Context: TFindContext;
IsEnd: Boolean; IsEnd: Boolean;
SearchForwardToo: Boolean;
begin begin
// for example 'AnObject[3]' // for example 'AnObject[3]'
@ -6975,9 +6998,16 @@ var
else else
Context:=ExprType.Context; Context:=ExprType.Context;
Params.ContextNode:=Context.Node; Params.ContextNode:=Context.Node;
SearchForwardToo:=false;
if Context.Node=StartNode then begin if Context.Node=StartNode then begin
// there is no special context -> search in parent contexts too // there is no special context -> search in parent contexts too
Params.Flags:=Params.Flags+[fdfSearchInParentNodes,fdfIgnoreCurContextNode]; Params.Flags:=Params.Flags+[fdfSearchInParentNodes,fdfIgnoreCurContextNode];
// check if searching forward too
if CanBeForwardDefined then begin
SearchForwardToo:=true;
Params.Flags:=Params.Flags-[fdfExceptionOnNotFound]
+[fdfIgnoreCurContextNode,fdfSearchForward];
end;
end else begin end else begin
// only search in special context // only search in special context
Params.Flags:=Params.Flags+[fdfIgnoreUsedUnits]; Params.Flags:=Params.Flags+[fdfIgnoreUsedUnits];
@ -6988,13 +7018,33 @@ var
then then
Include(Params.Flags,fdfIgnoreOverloadedProcs); Include(Params.Flags,fdfIgnoreOverloadedProcs);
// search ...
Params.SetIdentifier(Self,@Src[CurAtom.StartPos],@CheckSrcIdentifier); Params.SetIdentifier(Self,@Src[CurAtom.StartPos],@CheckSrcIdentifier);
// search ...
{$IFDEF ShowExprEval} {$IFDEF ShowExprEval}
DebugLn([' FindExpressionTypeOfTerm ResolveIdentifier SubIdent="',GetIdentifier(Params.Identifier),'" ContextNode="',Params.ContextNode.DescAsString,'" "',dbgstr(Context.Tool.Src,Params.ContextNode.StartPos,15),'" ',dbgs(Params.Flags)]); DebugLn([' FindExpressionTypeOfTerm ResolveIdentifier backward SubIdent="',GetIdentifier(Params.Identifier),'" ContextNode="',Params.ContextNode.DescAsString,'" "',dbgstr(Context.Tool.Src,Params.ContextNode.StartPos,15),'" ',dbgs(Params.Flags)]);
{$ENDIF} {$ENDIF}
ExprType.Desc:=xtNone;
// first search backwards
if Context.Tool.FindIdentifierInContext(Params) then begin if Context.Tool.FindIdentifierInContext(Params) then begin
ExprType.Desc:=xtContext; ExprType.Desc:=xtContext;
end else if SearchForwardToo then begin
// then search forwards
Params.Load(OldInput,false);
Params.SetIdentifier(Self,@Src[CurAtom.StartPos],@CheckSrcIdentifier);
Params.Flags:=[fdfSearchInParentNodes,fdfExceptionOnNotFound,
fdfIgnoreCurContextNode,fdfSearchForward]
+(fdfGlobals*Params.Flags);
Params.ContextNode:=Context.Node;
{$IFDEF ShowExprEval}
DebugLn([' FindExpressionTypeOfTerm ResolveIdentifier forward SubIdent="',GetIdentifier(Params.Identifier),'" ContextNode="',Params.ContextNode.DescAsString,'" "',dbgstr(Context.Tool.Src,Params.ContextNode.StartPos,15),'" ',dbgs(Params.Flags)]);
{$ENDIF}
if FindIdentifierInContext(Params) then begin
ExprType.Desc:=xtContext;
end;
end;
if ExprType.Desc=xtContext then begin
// identifier found
if Params.NewCodeTool.NodeIsConstructor(Params.NewNode) then begin if Params.NewCodeTool.NodeIsConstructor(Params.NewNode) then begin
// identifier is a constructor // identifier is a constructor
if (Context.Node.Desc in AllClassObjects) then begin if (Context.Node.Desc in AllClassObjects) then begin