FoxInterfaceComparison.Mod 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. MODULE FoxInterfaceComparison; (** AUTHOR "fof"; PURPOSE "compare interfaces / check symbol file compliances"; *)
  2. IMPORT Basic := FoxBasic, SyntaxTree := FoxSyntaxTree, Formats := FoxFormats, Fingerprinter := FoxFingerprinter, Global := FoxGlobal, SemanticChecker := FoxSemanticChecker, Diagnostics, Strings, D := Debugging;
  3. CONST
  4. Redefined*=0;
  5. Extended*=1;
  6. Trace=FALSE;
  7. PROCEDURE CompareThis*(module: SyntaxTree.Module; symbolFileFormat: Formats.SymbolFileFormat; diagnostics: Diagnostics.Diagnostics; importCache: SyntaxTree.ModuleScope; VAR flags: SET);
  8. VAR fname: Basic.FileName; importedModule: SyntaxTree.Module; fingerprinter: Fingerprinter.Fingerprinter;
  9. PROCEDURE SameType(new,old: SyntaxTree.Type): BOOLEAN;
  10. VAR fpNew,fpOld: SyntaxTree.Fingerprint;
  11. BEGIN
  12. old := old.resolved; new := new.resolved;
  13. IF old IS SyntaxTree.PointerType THEN
  14. old := old(SyntaxTree.PointerType).pointerBase;
  15. END;
  16. IF new IS SyntaxTree.PointerType THEN
  17. new := new(SyntaxTree.PointerType).pointerBase;
  18. END;
  19. fpNew := fingerprinter.TypeFP(new);
  20. fpOld := fingerprinter.TypeFP(old);
  21. IF Trace THEN
  22. D.String("-->"); D.Ln;
  23. D.String("fpOld "); Fingerprinter.DumpFingerprint(D.Log,fpOld); D.Ln;
  24. D.String("fpNew "); Fingerprinter.DumpFingerprint(D.Log,fpNew); D.Ln;
  25. END;
  26. RETURN (fpNew.private = fpOld.private) & (fpNew.public = fpOld.public) & (fpNew.shallow = fpOld.shallow);
  27. END SameType;
  28. PROCEDURE CompareSymbols(new,old: SyntaxTree.Symbol): BOOLEAN;
  29. VAR fpNew,fpOld: SyntaxTree.Fingerprint; oldType, newType: SyntaxTree.Type;
  30. BEGIN
  31. fpNew := fingerprinter.SymbolFP(new);
  32. fpOld := fingerprinter.SymbolFP(old);
  33. ASSERT(new.name=old.name);
  34. IF (fpNew.shallow # fpOld.shallow) THEN
  35. IF Trace THEN
  36. D.String("fp of "); D.Str0(new.name); D.Ln;
  37. D.String("fpOld "); Fingerprinter.DumpFingerprint(D.Log,fpOld); D.Ln;
  38. D.String("fpNew "); Fingerprinter.DumpFingerprint(D.Log,fpNew); D.Ln;
  39. END;
  40. RETURN FALSE
  41. ELSIF (new IS SyntaxTree.TypeDeclaration) & (old IS SyntaxTree.TypeDeclaration) THEN
  42. oldType := old(SyntaxTree.TypeDeclaration).declaredType;
  43. newType := new(SyntaxTree.TypeDeclaration).declaredType;
  44. IF ~SameType(newType,oldType) THEN
  45. IF Trace THEN
  46. D.String("<-- type fp of "); D.Str0(new.name); D.Ln;
  47. END;
  48. RETURN FALSE
  49. END;
  50. END;
  51. RETURN TRUE
  52. END CompareSymbols;
  53. PROCEDURE ErrorSS(pos: SyntaxTree.Position; CONST s1,s2: ARRAY OF CHAR);
  54. VAR msg: ARRAY 256 OF CHAR;
  55. BEGIN
  56. COPY(s1,msg);
  57. Strings.Append(msg,s2);
  58. IF (module # NIL) THEN
  59. Basic.Information(diagnostics, module.sourceName,pos,msg);
  60. END;
  61. END ErrorSS;
  62. PROCEDURE NextSymbol(symbol: SyntaxTree.Symbol): SyntaxTree.Symbol;
  63. BEGIN
  64. WHILE (symbol # NIL) & (symbol IS SyntaxTree.Import) DO
  65. symbol := symbol.nextSymbol;
  66. END;
  67. RETURN symbol
  68. END NextSymbol;
  69. PROCEDURE CompareScopes(new,old: SyntaxTree.Scope);
  70. VAR newSymbol, oldSymbol: SyntaxTree.Symbol;
  71. newName, oldName: SyntaxTree.IdentifierString;
  72. newPublic, oldPublic: BOOLEAN;
  73. BEGIN
  74. oldSymbol := NextSymbol(old.firstSymbol);
  75. newSymbol := NextSymbol(new.firstSymbol);
  76. WHILE (oldSymbol # NIL) & (newSymbol # NIL) DO
  77. Global.GetSymbolName(oldSymbol,oldName);
  78. Global.GetSymbolName(newSymbol,newName);
  79. oldPublic := oldSymbol.access * SyntaxTree.Public # {};
  80. newPublic := newSymbol.access * SyntaxTree.Public # {};
  81. IF oldName = newName THEN
  82. IF oldPublic = newPublic THEN
  83. IF ~CompareSymbols(newSymbol, oldSymbol) THEN
  84. ErrorSS(newSymbol.position,newName," is redefined");
  85. INCL(flags,Redefined);
  86. END;
  87. ELSIF oldPublic THEN
  88. ErrorSS(newSymbol.position,newName," is no longer visible");
  89. INCL(flags,Redefined);
  90. ELSIF newPublic THEN
  91. ErrorSS(newSymbol.position,newName," is new");
  92. INCL(flags,Extended);
  93. END;
  94. oldSymbol := NextSymbol(oldSymbol.nextSymbol);
  95. newSymbol := NextSymbol(newSymbol.nextSymbol);
  96. ELSIF oldName < newName THEN
  97. IF oldPublic THEN
  98. ErrorSS(Basic.invalidPosition,oldName," is no longer visible");
  99. INCL(flags,Redefined);
  100. END;
  101. oldSymbol := NextSymbol(oldSymbol.nextSymbol);
  102. ELSE
  103. IF newPublic THEN
  104. ErrorSS(newSymbol.position,newName," is new");
  105. INCL(flags,Extended);
  106. END;
  107. newSymbol := NextSymbol(newSymbol.nextSymbol);
  108. END;
  109. END;
  110. WHILE (oldSymbol # NIL) DO
  111. oldSymbol.GetName(oldName);
  112. oldPublic := oldSymbol.access * SyntaxTree.Public # {};
  113. IF oldSymbol.access * SyntaxTree.Public # {} THEN
  114. ErrorSS(Basic.invalidPosition,oldName," is no longer visible");
  115. INCL(flags,Redefined);
  116. END;
  117. oldSymbol := NextSymbol(oldSymbol.nextSymbol);
  118. END;
  119. WHILE (newSymbol # NIL) DO
  120. newSymbol.GetName(newName);
  121. newPublic := newSymbol.access * SyntaxTree.Public # {};
  122. IF newPublic THEN
  123. ErrorSS(newSymbol.position,newName," is new");
  124. INCL(flags,Extended);
  125. END;
  126. newSymbol := NextSymbol(newSymbol.nextSymbol);
  127. END;
  128. END CompareScopes;
  129. BEGIN
  130. Global.ModuleFileName(module.name,module.context,fname);
  131. importedModule := symbolFileFormat.Import(fname,importCache);
  132. NEW(fingerprinter);
  133. IF importedModule # NIL THEN
  134. CompareScopes(module.moduleScope,importedModule.moduleScope);
  135. IF importCache # NIL THEN SemanticChecker.RemoveModuleFromCache(importCache, importedModule) END;
  136. ELSE
  137. (* ErrorSS(Streams.Invalid,fname," new module."); *)
  138. END;
  139. END CompareThis;
  140. END FoxInterfaceComparison.