📄 dws2ideutils.pas
字号:
locProgram.Free;
locProgram := CompileWithSymbolsAndMap(Compiler, ScriptText.Text);
// if nothing was changed and there are still errors, show message and abort.
if (not ChangedInLoop) and (Length(locProgram.ClassCompleteNeeds) > 0) then
if (AClassName = '') or SameText(AClassName, ErrorClassName) then
raise Exception.CreateFmt('Unable to complete class "%s". Correct other script errors first.', [ErrorClassName]);
until (Length(locProgram.ClassCompleteNeeds) = 0) or (not ChangedInLoop);
finally
locProgram.Free;
end;
end;
{-----------------------------------------------------------------------------
Procedure: SymbolToString
Author: Mark Ericksen
Date: 08-Oct-2002
Arguments: Symbol: TSymbol
Result: string
Purpose: Return the source string version of a compiled symbol. This would
be in a format suitable for code completion, hints, etc.
-----------------------------------------------------------------------------}
function SymbolToString(Symbol: TSymbol): string;
begin
{ TODO -oMark : Use a formating method parameter? Make it work for new SynEdit, old, plain text, etc }
end;
{-----------------------------------------------------------------------------
Procedure: FindFuncDeclImplOnLine
Author: Mark Ericksen
Date: 17-Oct-2002
Arguments: ALine: Integer; Dictionary: TSymbolDictionary
Result: TSymbol
Purpose: Return the function symbol that is either declared or implemented
on the specified line. Returns nil if nothing fits it.
-----------------------------------------------------------------------------}
function FindFuncDeclImplOnLine(ALine: Integer; Dictionary: TSymbolDictionary): TSymbolPosition;
var
i: Integer;
Declared, Implement: TSymbolPosition;
begin
Result := nil;
for i := 0 to Dictionary.Count - 1 do
begin
{ If a method, look for Declaration, Implementation }
if Dictionary[i].Symbol is TMethodSymbol then
begin
Declared := Dictionary[i].FindUsage(suDeclaration);
if Assigned(Declared) then
if Declared.ScriptPos.Line = ALine then
Result := Declared;
Implement:= Dictionary[i].FindUsage(suImplementation);
if Assigned(Implement) then
if Implement.ScriptPos.Line = ALine then
Result := Implement;
end
{ If a function (not method), look for Forward, Declaration }
else if Dictionary[i].Symbol is TFuncSymbol then
begin
// forwards are the early declarations
Declared := Dictionary[i].FindUsage(suForward);
if Assigned(Declared) then
if Declared.ScriptPos.Line = ALine then
Result := Declared;
// declaration is the implementation for functions
Implement:= Dictionary[i].FindUsage(suDeclaration);
if Assigned(Implement) then
if Implement.ScriptPos.Line = ALine then
Result := Implement;
end;
if Assigned(Result) then
Break;
end; {for}
end;
{-----------------------------------------------------------------------------
Procedure: FindFuncTogglePosition
Author: Mark Ericksen
Date: 07-Jan-2003
Arguments: Symbol: TSymbol; FromUsages: TSymbolUsages; Dictionary: TSymbolDictionary
Result: TSymbolPosition
Purpose: Return the symbol position that corresponds to the current function
or method. This is used to jump from a method declaration to the
interface and back. A function (non-method) can have a 'forward'
and this can be used as a jump point.
-----------------------------------------------------------------------------}
function FindFuncTogglePosition(Symbol: TSymbol; FromUsages: TSymbolUsages; Dictionary: TSymbolDictionary): TSymbolPosition;
begin
Result := nil;
if not Assigned(Symbol) then Exit;
{ If a method, determine toggled usage }
if Symbol is TMethodSymbol then
begin
if suDeclaration in FromUsages then
Result := Dictionary.FindSymbolUsage(Symbol, suImplementation)
else if suImplementation in FromUsages then
Result := Dictionary.FindSymbolUsage(Symbol, suDeclaration);
end
{ If a function, determine toggled usage }
else if Symbol is TFuncSymbol then
begin
if suForward in FromUsages then
Result := Dictionary.FindSymbolUsage(Symbol, suImplementation)
else if (suDeclaration in FromUsages) or (suImplementation in FromUsages) then
Result := Dictionary.FindSymbolUsage(Symbol, suForward);
end;
end;
{-----------------------------------------------------------------------------
Procedure: FindFuncContext
Author: Mark Ericksen
Date: 07-Jan-2003
Arguments: ACol, ALine: Integer; ContextMap: TContextMap
Result: TFuncSymbol
Purpose: Find the Function symbol associated with the current location in
the script. Nil is returned if none found.
-----------------------------------------------------------------------------}
function FindFuncContext(ACol, ALine: Integer; ContextMap: TContextMap): TFuncSymbol;
var
Context: TContext;
begin
Result := nil;
Context := ContextMap.FindContext(ACol, ALine);
if Assigned(Context) then
begin
{ Determine if context is a function. Go up parent tree until reach top. }
repeat
if Context.ParentSym is TFuncSymbol then
Result := TFuncSymbol(Context.ParentSym)
else
Context := Context.Parent;
until Assigned(Result) or (Context = nil);
end;
end;
{-----------------------------------------------------------------------------
Procedure: GetPropertyForSymbol
Author: Mark Ericksen
Date: 20-Nov-2002
Arguments: ASym: TSymbol
Result: TPropertySymbol
Purpose: Given a symbol, return the property for which it is either
a read or write access method. Currently only applies to
TMethodSymbols and TFieldSymbols.
-----------------------------------------------------------------------------}
function GetPropertyForSymbol(ASym: TSymbol): TPropertySymbol;
var
i: Integer;
ClassSym: TClassSymbol;
begin
Result := nil;
if ASym is TMethodSymbol then
ClassSym := TMethodSymbol(ASym).ClassSymbol
else if ASym is TFieldSymbol then
ClassSym := TFieldSymbol(ASym).ClassSymbol
else
ClassSym := nil;
if Assigned(ClassSym) and Assigned(ASym) then
begin
for i := 0 to ClassSym.Members.Count - 1 do
begin
if ClassSym.Members[i] is TPropertySymbol then
if (TPropertySymbol(ClassSym.Members[i]).ReadSym = ASym) or
(TPropertySymbol(ClassSym.Members[i]).WriteSym = ASym)
then
begin
// Return pointer to the property symbol
Result := TPropertySymbol(ClassSym.Members[i]);
Break;
end;
end;
end;
end;
{-----------------------------------------------------------------------------
Procedure: SymbolIsPropertyRead
Author: Mark Ericksen
Date: 07-Jan-2003
Arguments: AProperty: TPropertySymbol; ASym: TSymbol
Result: Boolean
Purpose: Return if a symbol is used in the 'read' portion of an object property.
-----------------------------------------------------------------------------}
function SymbolIsPropertyRead(AProperty: TPropertySymbol; ASym: TSymbol): Boolean;
begin
// Pointer match is the answer.
Result := False;
if Assigned(AProperty) and Assigned(ASym) then
Result := AProperty.ReadSym = ASym;
end;
{-----------------------------------------------------------------------------
Procedure: MethodIsWrite
Author: Mark Ericksen
Date: 07-Jan-2003
Arguments: AProperty: TPropertySymbol; AFunc: TFuncSymbol
Result: Boolean
Purpose: Return if a method is used in the 'write' portion of an object property.
-----------------------------------------------------------------------------}
function SymbolIsPropertyWrite(AProperty: TPropertySymbol; ASym: TSymbol): Boolean;
begin
// Pointer match is the answer.
Result := False;
if Assigned(AProperty) and Assigned(ASym) then
Result := AProperty.WriteSym = ASym;
end;
{-----------------------------------------------------------------------------
Procedure: FindToggledFuncDeclImplPos
Author: Mark Ericksen
Date: 05-Dec-2002
Arguments: ACol, ALine: Integer; AProgram: TProgram
Result: TScriptPos (If not found, NullPos is returned (values are -1)
Purpose: Return toggled position between Implementation and Declaration
(procedures/methods)
-----------------------------------------------------------------------------}
function FindToggledFuncDeclImplPos(ACol, ALine: Integer; AProgram: TProgram): TScriptPos;
var
SymPos,
TogglePos: TSymbolPosition;
FuncSym: TFuncSymbol;
FromUsages: TSymbolUsages;
begin
SymPos := FindFuncDeclImplOnLine(ALine, AProgram.SymbolDictionary);
{ If assigned, use the function symbol }
if Assigned(SymPos) then
begin
FuncSym := TFuncSymbol(SymPos.Symbol);
FromUsages := SymPos.SymbolUsages;
end
{ If nothing found, check context }
else
begin
FuncSym := FindFuncContext(ACol, ALine, AProgram.ContextMap);
FromUsages := [suImplementation];
end;
{ If we found the function symbol in question, find where to jump to. }
if Assigned(FuncSym) then
begin
TogglePos := FindFuncTogglePosition(FuncSym, FromUsages, AProgram.SymbolDictionary);
if Assigned(TogglePos) then
Result := TogglePos.ScriptPos // Return position
else
Result := NullPos; // return invalid position
end;
end;
{-----------------------------------------------------------------------------
Procedure: SymbolDeclBeforePos
Author: Mark Ericksen
Date: 21-Mar-2003
Arguments: ACol, ALine: Integer; AProgram: TProgram; ASymbol: TSymbol
Result: Boolean
Purpose: Determine if a position (ACol, ALine) is before the declaration of
a symbol.
-----------------------------------------------------------------------------}
function SymbolDeclBeforePos(ACol, ALine: Integer; AProgram: TProgram; ASymbol: TSymbol): Boolean;
var
SymPos: TSymbolPosition;
begin
Assert(AProgram <> nil);
Assert(ASymbol <> nil);
// Check if position is before declaration position
SymPos := AProgram.SymbolDictionary.FindSymbolUsage(ASymbol, suDeclaration);
if Assigned(SymPos) then
// if same line and before column position or on a previous line
Result := ((ALine = SymPos.ScriptPos.Line) and (SymPos.ScriptPos.Col <= ACol ))
or (SymPos.ScriptPos.Line < ALine)
else // if declaration of symbol not found, then assumed prior to position
Result := True;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -