⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dws2ideutils.pas

📁 script language
💻 PAS
📖 第 1 页 / 共 4 页
字号:
      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 + -