codetools: param completion for @pointertype

git-svn-id: trunk@34714 -
This commit is contained in:
mattias 2012-01-12 14:10:11 +00:00
parent 034d195ca9
commit 724765c335
2 changed files with 55 additions and 18 deletions

View File

@ -1883,9 +1883,8 @@ begin
and (Src[VarNameAtom.StartPos]='@') then begin and (Src[VarNameAtom.StartPos]='@') then begin
HasAtOperator:=true; HasAtOperator:=true;
inc(VarNameAtom.StartPos); inc(VarNameAtom.StartPos);
// ToDo: resolve pointer: @p to a PFindContext create p:TFindContext
// ToDo: create event: @OnClick to a TNotifyEvent create a method // ToDo: create event: @OnClick to a TNotifyEvent create a method
exit; //debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter HasAtOperator ',GetAtom(VarNameAtom)]);
end; end;
if not IsValidIdent(GetAtom(VarNameAtom)) then exit; if not IsValidIdent(GetAtom(VarNameAtom)) then exit;
@ -1934,7 +1933,6 @@ begin
CleanPosToCodePos(VarNameAtom.StartPos,IgnorePos); CleanPosToCodePos(VarNameAtom.StartPos,IgnorePos);
IgnoreErrorAfter:=IgnorePos; IgnoreErrorAfter:=IgnorePos;
try try
debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter ToDo: check for overloads']);
if not Context.Tool.FindIdentifierInContext(Params) then exit; if not Context.Tool.FindIdentifierInContext(Params) then exit;
finally finally
ClearIgnoreErrorAfter; ClearIgnoreErrorAfter;
@ -1947,7 +1945,7 @@ begin
ParameterIndex); ParameterIndex);
if (ParameterNode=nil) if (ParameterNode=nil)
and (Params.NewNode.Desc in [ctnProperty,ctnProcedure]) then begin and (Params.NewNode.Desc in [ctnProperty,ctnProcedure]) then begin
DebugLn(' CompleteLocalVariableAsParameter Procedure does not have so many parameters'); DebugLn([' CompleteLocalVariableAsParameter Procedure has less than ',ParameterIndex+1,' parameters']);
exit; exit;
end; end;
if ParameterNode<>nil then begin if ParameterNode<>nil then begin
@ -1969,17 +1967,47 @@ begin
AliasType:=CleanFindContext; AliasType:=CleanFindContext;
ExprType:=TypeTool.FindExpressionResultType(Params, ExprType:=TypeTool.FindExpressionResultType(Params,
TypeNode.StartPos,TypeNode.EndPos,@AliasType); TypeNode.StartPos,TypeNode.EndPos,@AliasType);
//debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter AliasType=',FindContextToString(AliasType)]); //debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter parameter type: AliasType=',FindContextToString(AliasType)]);
if HasAtOperator then begin
//debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter HasAtOperator ExprType=',ExprTypeToString(ExprType)]);
NewType:='';
if (ExprType.Desc=xtContext)
and (ExprType.Context.Node<>nil) then begin
TypeNode:=ExprType.Context.Node;
TypeTool:=ExprType.Context.Tool;
if (TypeNode.Desc=ctnPointerType) then begin
// for example PMapID = ^...
if (TypeNode.FirstChild<>nil)
and (TypeNode.FirstChild.Desc=ctnIdentifier) then begin
// for example PMapID = ^TMapID
NewType:=TypeTool.ExtractCode(TypeNode.FirstChild.StartPos,
TypeNode.FirstChild.EndPos,[]);
debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter pointer to ',NewType]);
Params.Clear;
Params.ContextNode:=TypeNode;
Params.Flags:=fdfDefaultForExpressions;
AliasType:=CleanFindContext;
ExprType:=TypeTool.FindExpressionResultType(Params,
TypeNode.FirstChild.StartPos,TypeNode.FirstChild.EndPos,
@AliasType);
debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter parameter is pointer to type: AliasType=',FindContextToString(AliasType)]);
end;
end else begin
end;
end;
if NewType='' then begin
debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter parameter has @ operator, but this is not implemented for ',ExprTypeToString(ExprType)]);
exit;
end;
end;
if AliasType.Node<>nil then begin if AliasType.Node<>nil then begin
// an identifier // an identifier
MissingUnitName:=GetUnitNameForUsesSection(AliasType.Tool); MissingUnitName:=GetUnitNameForUsesSection(AliasType.Tool);
//debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter MissingUnitName=',MissingUnitName]); //debugln(['TCodeCompletionCodeTool.CompleteLocalVariableByParameter MissingUnitName=',MissingUnitName]);
end; end;
if HasAtOperator then begin
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=""');

View File

@ -182,7 +182,7 @@ const
fdfOnlyCompatibleProc, fdfSearchInAncestors, fdfCollect]; fdfOnlyCompatibleProc, fdfSearchInAncestors, fdfCollect];
// initial flags for searches // initial flags for searches
fdfDefaultForExpressions = [fdfSearchInParentNodes, fdfSearchInAncestors, fdfDefaultForExpressions = [fdfSearchInParentNodes, fdfSearchInAncestors,
fdfExceptionOnNotFound]; fdfExceptionOnNotFound,fdfIgnoreCurContextNode];
// for nicer output // for nicer output
FindDeclarationFlagNames: array[TFindDeclarationFlag] of string = ( FindDeclarationFlagNames: array[TFindDeclarationFlag] of string = (
@ -6324,7 +6324,7 @@ begin
try try
TypeParams.ContextNode:=TypeNode; TypeParams.ContextNode:=TypeNode;
TypeParams.SetIdentifier(Self,nil,nil); TypeParams.SetIdentifier(Self,nil,nil);
TypeParams.Flags:=fdfDefaultForExpressions+[fdfIgnoreCurContextNode]; TypeParams.Flags:=fdfDefaultForExpressions;
ExprType:=FindExpressionTypeOfTerm(TypeNode.StartPos,-1,TypeParams,false); ExprType:=FindExpressionTypeOfTerm(TypeNode.StartPos,-1,TypeParams,false);
//debugln(['TFindDeclarationTool.FindIdentifierInTypeOfConstant ExprType=',ExprTypeToString(ExprType)]); //debugln(['TFindDeclarationTool.FindIdentifierInTypeOfConstant ExprType=',ExprTypeToString(ExprType)]);
finally finally
@ -9009,10 +9009,12 @@ function TFindDeclarationTool.CheckParameterSyntax(CursorNode: TCodeTreeNode;
ReadNextAtom; ReadNextAtom;
{$IFDEF VerboseCPS}DebugLn('CheckIdentifierAndParameterList Atom="',GetAtom,'"');{$ENDIF} {$IFDEF VerboseCPS}DebugLn('CheckIdentifierAndParameterList Atom="',GetAtom,'"');{$ENDIF}
if (CurPos.EndPos>CleanCursorPos) if (CurPos.EndPos>CleanCursorPos)
or ((CurPos.EndPos=CleanCursorPos) and (CurPos.Flag=cafWord)) then begin or ((CurPos.EndPos=CleanCursorPos)
and ((CurPos.Flag=cafWord) or AtomIsChar('@')))
then begin
// parameter found => search parameter expression bounds e.g. ', parameter ,' // parameter found => search parameter expression bounds e.g. ', parameter ,'
// important: this function should work, even the code behind // important: this function should work, even if the code
// CleanCursorPos is buggy // behind CleanCursorPos has syntax errors
{$IFDEF VerboseCPS}DebugLn('CheckIdentifierAndParameterList Parameter found, search range ...');{$ENDIF} {$IFDEF VerboseCPS}DebugLn('CheckIdentifierAndParameterList Parameter found, search range ...');{$ENDIF}
ProcNameAtom:=CurProcNameAtom; ProcNameAtom:=CurProcNameAtom;
ParameterIndex:=CurParameterIndex; ParameterIndex:=CurParameterIndex;
@ -9023,20 +9025,27 @@ function TFindDeclarationTool.CheckParameterSyntax(CursorNode: TCodeTreeNode;
ReadNextAtom; ReadNextAtom;
{$IFDEF VerboseCPS}DebugLn('CheckIdentifierAndParameterList parameter atom "',GetAtom,'"');{$ENDIF} {$IFDEF VerboseCPS}DebugLn('CheckIdentifierAndParameterList parameter atom "',GetAtom,'"');{$ENDIF}
if (CurPos.Flag in [cafRoundBracketOpen,cafEdgedBracketOpen]) then if (CurPos.Flag in [cafRoundBracketOpen,cafEdgedBracketOpen]) then
ReadTilBracketClose(false) begin
// atom belongs to the parameter expression
if ParameterAtom.StartPos=ParameterAtom.EndPos then
ParameterAtom.StartPos:=CurPos.StartPos;
ReadTilBracketClose(false);
ParameterAtom.EndPos:=CurPos.EndPos;
end
else else
if (CurPos.Flag in [cafNone,cafComma,cafSemicolon,cafEnd, if (CurPos.StartPos>SrcLen)
or (CurPos.Flag in [cafComma,cafSemicolon,cafEnd,
cafRoundBracketClose,cafEdgedBracketClose]) cafRoundBracketClose,cafEdgedBracketClose])
or ((CurPos.Flag=cafWord) or ((CurPos.Flag=cafWord)
and (LastAtoms.GetValueAt(0).Flag=cafWord) and (LastAtoms.GetValueAt(0).Flag=cafWord)
and (not LastUpAtomIs(0,'INHERITED'))) then and (not LastUpAtomIs(0,'INHERITED'))) then
begin begin
// end of parameter expression found // end of parameter expression found
{$IFDEF VerboseCPS}DebugLn('CheckIdentifierAndParameterList end of parameter found');{$ENDIF} {$IFDEF VerboseCPS}DebugLn('CheckIdentifierAndParameterList end of parameter found "',GetAtom,'" Parameter="',dbgstr(Src,ParameterAtom.StartPos,ParameterAtom.EndPos-ParameterAtom.StartPos),'"');{$ENDIF}
exit(true); exit(true);
end else begin end else begin
// atom belongs to the parameter expression // atom belongs to the parameter expression
if ParameterAtom.StartPos=ParameterStart then if ParameterAtom.StartPos=ParameterAtom.EndPos then
ParameterAtom.StartPos:=CurPos.StartPos; ParameterAtom.StartPos:=CurPos.StartPos;
ParameterAtom.EndPos:=CurPos.EndPos; ParameterAtom.EndPos:=CurPos.EndPos;
end; end;