diff --git a/src/Runtime/XSharp.VFP.UI/MenuFunctions.prg b/src/Runtime/XSharp.VFP.UI/MenuFunctions.prg
index 030a3ce7ba..ba4e3830a2 100644
--- a/src/Runtime/XSharp.VFP.UI/MenuFunctions.prg
+++ b/src/Runtime/XSharp.VFP.UI/MenuFunctions.prg
@@ -15,6 +15,7 @@ USING XSharp.VFP.UI
/// Returns the 1-based number of the most recently selected menu bar item.
/// Returns 0 if no item was selected or the user pressed ESC.
///
+[FoxProFunction("BAR", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.Full, FoxCriticality.Medium)];
FUNCTION BAR() AS INT
RETURN MenuState.LastBar
@@ -22,6 +23,7 @@ FUNCTION BAR() AS INT
/// Returns the name of the most recently selected menu pad (top-level title).
/// Returns an empty string if no pad was selected.
///
+[FoxProFunction("PAD", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.Full, FoxCriticality.Medium)];
FUNCTION PAD() AS STRING
RETURN MenuState.LastPad
@@ -29,6 +31,7 @@ FUNCTION PAD() AS STRING
/// Returns the name of the popup that contained the last selected bar.
/// Returns an empty string if no popup was active.
///
+[FoxProFunction("POPUP", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.Full, FoxCriticality.Medium)];
FUNCTION POPUP() AS STRING
RETURN MenuState.LastPopup
@@ -36,6 +39,7 @@ FUNCTION POPUP() AS STRING
/// Returns the name of the menu bar that was active when the last selection occurred.
/// Returns an empty string if no menu was active.
///
+[FoxProFunction("MENU", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.Full, FoxCriticality.Medium)];
FUNCTION MENU() AS STRING
RETURN MenuState.LastMenu
@@ -43,6 +47,7 @@ FUNCTION MENU() AS STRING
/// Returns .T. if the specified bar item is currently checked (marked).
/// — name of the Popup; — 1-based bar number.
///
+[FoxProFunction("MRKBAR", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.Full, FoxCriticality.Medium)];
FUNCTION MRKBAR( cPopupName AS STRING, nBar AS INT ) AS LOGIC
LOCAL oPopup := Popup.Find(cPopupName) AS Popup
IF oPopup != NULL .AND. nBar >= 1 .AND. nBar <= oPopup:BarCount
@@ -54,6 +59,7 @@ FUNCTION MRKBAR( cPopupName AS STRING, nBar AS INT ) AS LOGIC
/// Returns .T. if the specified pad is currently checked (marked).
/// — name of the Menu; — pad name.
///
+[FoxProFunction("MRKPAD", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.Full, FoxCriticality.Medium)];
FUNCTION MRKPAD( cMenuName AS STRING, cPadName AS STRING ) AS LOGIC
LOCAL oMenu := Menu.Find(cMenuName) AS Menu
IF oMenu != NULL
@@ -70,6 +76,7 @@ FUNCTION MRKPAD( cMenuName AS STRING, cPadName AS STRING ) AS LOGIC
/// Returns the prompt (caption) text of the specified bar item.
/// — name of the Popup; — 1-based bar number.
///
+[FoxProFunction("PRMBAR", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.Full, FoxCriticality.Medium)];
FUNCTION PRMBAR( cPopupName AS STRING, nBar AS INT ) AS STRING
LOCAL oPopup := Popup.Find(cPopupName) AS Popup
IF oPopup != NULL .AND. nBar >= 1 .AND. nBar <= oPopup:BarCount
@@ -81,6 +88,7 @@ FUNCTION PRMBAR( cPopupName AS STRING, nBar AS INT ) AS STRING
/// Returns the prompt (caption) text of the specified pad.
/// — name of the Menu; — pad name.
///
+[FoxProFunction("PRMPAD", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.Full, FoxCriticality.Medium)];
FUNCTION PRMPAD( cMenuName AS STRING, cPadName AS STRING ) AS STRING
LOCAL oMenu := Menu.Find(cMenuName) AS Menu
IF oMenu != NULL
diff --git a/src/Runtime/XSharp.VFP/NotSupported.prg b/src/Runtime/XSharp.VFP/NotSupported.prg
index 254c1c4b4e..554c85c830 100644
--- a/src/Runtime/XSharp.VFP/NotSupported.prg
+++ b/src/Runtime/XSharp.VFP/NotSupported.prg
@@ -65,11 +65,6 @@ RETURN NIL
FUNCTION AVCXCLASSES( )
RETURN NIL
-[Obsolete( "This function will not be supported" )];
-[FoxProFunction("BAR", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
-FUNCTION BAR( )
-RETURN NIL
-
[Obsolete( "This function will not be supported" )];
[FoxProFunction("BARCOUNT", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
FUNCTION BARCOUNT( )
@@ -231,26 +226,11 @@ RETURN NIL
FUNCTION MEMORY( )
RETURN NIL
-[Obsolete( "This function will not be supported" )];
-[FoxProFunction("MENU", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
-FUNCTION MENU( )
-RETURN NIL
-
[Obsolete( "This function will not be supported" )];
[FoxProFunction("MESSAGE", FoxFunctionCategory.EnvironmentAndSystem, FoxEngine.LanguageCore, FoxFunctionStatus.NotSupported, FoxCriticality.High)];
FUNCTION MESSAGE( )
RETURN NIL
-[Obsolete( "This function will not be supported" )];
-[FoxProFunction("MRKBAR", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
-FUNCTION MRKBAR( )
-RETURN NIL
-
-[Obsolete( "This function will not be supported" )];
-[FoxProFunction("MRKPAD", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
-FUNCTION MRKPAD( )
-RETURN NIL
-
[Obsolete( "This function will not be supported" )];
[FoxProFunction("MROW", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
FUNCTION MROW( )
@@ -271,11 +251,6 @@ RETURN NIL
FUNCTION ON( )
RETURN NIL
-[Obsolete( "This function will not be supported" )];
-[FoxProFunction("PAD", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
-FUNCTION Pad( )
-RETURN NIL
-
[Obsolete( "This function will not be supported" )];
[FoxProFunction("PADPROMPT", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
FUNCTION PADPROMPT( )
@@ -291,26 +266,11 @@ RETURN NIL
FUNCTION PEMSTATUS( )
RETURN NIL
-[Obsolete( "This function will not be supported" )];
-[FoxProFunction("POPUP", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
-FUNCTION POPUP( )
-RETURN NIL
-
[Obsolete( "This function will not be supported" )];
[FoxProFunction("PRINTSTATUS", FoxFunctionCategory.EnvironmentAndSystem, FoxEngine.RuntimeCore, FoxFunctionStatus.NotSupported, FoxCriticality.Low)];
FUNCTION PRINTSTATUS( )
RETURN NIL
-[Obsolete( "This function will not be supported" )];
-[FoxProFunction("PRMBAR", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
-FUNCTION PRMBAR( )
-RETURN NIL
-
-[Obsolete( "This function will not be supported" )];
-[FoxProFunction("PRMPAD", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
-FUNCTION PRMPAD( )
-RETURN NIL
-
[Obsolete( "This function will not be supported" )];
[FoxProFunction("PROMPT", FoxFunctionCategory.UIAndWindow, FoxEngine.UI, FoxFunctionStatus.NotSupported, FoxCriticality.Medium)];
FUNCTION PROMPT( )
diff --git a/src/Tools/VfpTools/VfpCompatMetrics/Program.prg b/src/Tools/VfpTools/VfpCompatMetrics/Program.prg
index 17a7445188..2ab3b9d52d 100644
--- a/src/Tools/VfpTools/VfpCompatMetrics/Program.prg
+++ b/src/Tools/VfpTools/VfpCompatMetrics/Program.prg
@@ -446,23 +446,54 @@ BEGIN NAMESPACE VfpCompatMetrics
// 7. CLI entry point
// =========================================================================
CLASS Program
+ STATIC METHOD StatusRank(cStatus AS STRING) AS INT
+ DO CASE
+ CASE cStatus == "Full" .OR. cStatus == "Intrinsic"; RETURN 4
+ CASE cStatus == "Partial"; RETURN 3
+ CASE cStatus == "Stub"; RETURN 2
+ CASE cStatus == "NotSupported"; RETURN 1
+ OTHERWISE; RETURN 0
+ END CASE
+ END METHOD
+
STATIC METHOD Start(args AS STRING[]) AS INT
IF args:Length == 0
- Console.WriteLine("Usage for Audit: vfpCompatMetrics ")
- Console.WriteLine("Usage for Inventory: vfpCompatMetrics ")
+ Console.WriteLine("Usage for Audit: vfpCompatMetrics [ ...] ")
+ Console.WriteLine("Usage for Inventory: vfpCompatMetrics [ ...]")
RETURN 1
ENDIF
- VAR asmPath := args[0]
- var isInventoryMode := (args:Length == 1) // Si solo hay 1 argumento, es Inventario
+ // Las funciones VFP no viven solo en XSharp.VFP: las de menus estan en
+ // XSharp.VFP.UI. Se admiten varios ensamblados; el .json es el universo.
+ VAR asmPaths := List{}
+ VAR jsonPath := ""
+ FOREACH a AS STRING IN args
+ IF a:ToLower():EndsWith(".json")
+ jsonPath := a
+ ELSE
+ asmPaths:Add(a)
+ ENDIF
+ NEXT
+ var isInventoryMode := String.IsNullOrEmpty(jsonPath)
TRY
- Console.WriteLine("Loading assembly for analysis: " + asmPath)
- VAR asm := AssemblyLoader.Load(asmPath)
-
- Console.WriteLine("Extracting runtime metadata...")
- VAR metadataList := MetadataExtractor.Extract(asm)
+ VAR metadataList := List{}
+ FOREACH asmPath AS STRING IN asmPaths
+ Console.WriteLine("Loading assembly for analysis: " + asmPath)
+ VAR asm := AssemblyLoader.Load(asmPath)
+ Console.WriteLine("Extracting runtime metadata...")
+ FOREACH item AS FoxFunctionMetadata IN MetadataExtractor.Extract(asm)
+ // Una funcion declarada en dos ensamblados cuenta una vez, con el mejor estado
+ VAR prev := metadataList:Find({ x => x:Name == item:Name })
+ IF prev == NULL
+ metadataList:Add(item)
+ ELSEIF StatusRank(item:Status) > StatusRank(prev:Status)
+ metadataList:Remove(prev)
+ metadataList:Add(item)
+ ENDIF
+ NEXT
+ NEXT
IF !Console.IsOutputRedirected
Console.Clear()
@@ -471,7 +502,6 @@ BEGIN NAMESPACE VfpCompatMetrics
if isInventoryMode
ReportPrinter.PrintInventory(metadataList)
else
- var jsonPath := args[1]
Console.WriteLine("Loading theoretical universe from JSON...")
var jsonString := File.ReadAllText(jsonPath)