Compilation error "Class xxx has no default properties" when registered from code, not from UI

Issue #177 new
John Riche created an issue

When running a script with objects defined in code, I receive the "" error. When I define objects using Delphi UI, the script is working fine. I'm not sure what could be the cause of this problem as I can't see any differences between both declarations. Am I missing something ?

Here is the declaration for a basic TStrings / TStringList:

// -- Init
aUnit.UnitName := 'SampleUnit';

// -- Methods
aFunction := aUnit.Functions.Add;
aFunction.Name := 'Debug';
aFunction.OnEval := dwsUnit1FunctionsDebugEval;
  // Param: Index
  aParameter := aFunction.Parameters.Add;
  aParameter.Name := 'Value';
  aParameter.DataType := 'String';
  aParameter.IsWritable := False;

// -- TStrings
aClass := aUnit.Classes.Add;
aClass.Name := 'TStrings';

  // Constructor
  aConstructor := aClass.Constructors.Add;
  aConstructor.Name := 'Create';
  aConstructor.OnEval := Self.dwsUnit1ClassesTStringsConstructorsCreateEval;

  // Method: GetStrings
  aMethod := aClass.Methods.Add;
  aMethod.Name := 'GetStrings';
  aMethod.Kind := mkFunction;
  aMethod.ResultType := 'String';
  aMethod.Visibility := cvPrivate;
  aMethod.OnEval := Self.dwsUnit1ClassesTStringsMethodsGetStringsEval;
    // Param: Index
    aParameter := aMethod.Parameters.Add;
    aParameter.Name := 'Index';
    aParameter.DataType := 'Integer';
    aParameter.IsWritable := False;

  // Method: SetStrings
  aMethod := aClass.Methods.Add;
  aMethod.Name := 'SetStrings';
  aMethod.Kind := mkProcedure;
  aMethod.Visibility := cvPrivate;
  aMethod.OnEval := Self.dwsUnit1ClassesTStringsMethodsSetStringsEval;
    // Param: Index
    aParameter := aMethod.Parameters.Add;
    aParameter.Name := 'Index';
    aParameter.DataType := 'Integer';
    aParameter.IsWritable := False;
    // Param: Value
    aParameter := aMethod.Parameters.Add;
    aParameter.Name := 'Value';
    aParameter.DataType := 'String';
    aParameter.IsWritable := False;

  // Property: Strings
  aProperty := aClass.Properties.Add;
  aProperty.Name := 'Strings';
  aProperty.DataType := 'String';
  aProperty.IsDefault := True;
  aProperty.ReadAccess := 'GetStrings';
  aProperty.WriteAccess := 'SetStrings';
  aProperty.Visibility := cvPublic;
    // Parameter: x
    aParameter := aProperty.Parameters.Add;
    aParameter.Name := 'x';
    aParameter.DataType := 'Integer';
    aParameter.IsWritable := False;

// -- TStringList
aClass := aUnit.Classes.Add;
aClass.Name := 'TStringList';
aClass.Ancestor := 'TStrings';

  // Constructor
  aConstructor := aClass.Constructors.Add;
  aConstructor.Name := 'Create';
  aConstructor.OnEval := Self.dwsUnit1ClassesTStringListConstructorsCreateEval;

// -- Include unit
aUnit.Script := aScript;

Here is the script:

var
  aList: TStringList;
begin
  aList := TStringList.Create;
  Debug(aList[0]);  // <-- Should compile fine but compilation error: Syntax Error: Class "TStringList" has no default property [line: 5, column: 14]
end.

Attached is the full sample project with example of both.

Comments (1)

  1. John Riche reporter

    OK I think I figured it out: for the “strings property, the aProperty.IsDefault := True; must be declared AFTER the parameter because of this code:

    // SetIsDefault
    //
    procedure TdwsProperty.SetIsDefault(Value: Boolean);
    var
      i: Integer;
      properties: TdwsProperties;
    begin
      Value := Value and (Parameters.Count > 0);
      //...
    

    That was a hard one to find!

  2. Log in to comment