Changeset 11682 in josm for trunk/tools/japicc


Ignore:
Timestamp:
2017-03-05T01:25:59+01:00 (3 years ago)
Author:
Don-vip
Message:

update to japi-compliance-checker 2.1

Location:
trunk/tools/japicc
Files:
22 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/japicc/japi-compliance-checker.pl

    r10845 r11682  
    11#!/usr/bin/perl
    22###########################################################################
    3 # Java API Compliance Checker (JAPICC) 1.8
     3# Java API Compliance Checker (JAPICC) 2.1
    44# A tool for checking backward compatibility of a Java library API
    55#
    66# Written by Andrey Ponomarenko
    77#
    8 # Copyright (C) 2011 Institute for System Programming, RAS
    9 # Copyright (C) 2011-2016 Andrey Ponomarenko's ABI Laboratory
     8# Copyright (C) 2011-2017 Andrey Ponomarenko's ABI Laboratory
    109#
    1110# PLATFORMS
     
    4039use File::Path qw(mkpath rmtree);
    4140use File::Temp qw(tempdir);
    42 use File::Copy qw(copy);
    43 use File::Spec::Functions qw(abs2rel);
     41use File::Basename qw(dirname);
    4442use Cwd qw(abs_path cwd);
    4543use Data::Dumper;
    46 use Digest::MD5 qw(md5_hex);
    47 use Config;
    48 
    49 my $TOOL_VERSION = "1.8";
    50 my $API_DUMP_VERSION = "2.0";
    51 my $API_DUMP_MAJOR = majorVersion($API_DUMP_VERSION);
    52 
    53 my ($Help, $ShowVersion, %Descriptor, $TargetLibraryName, $CheckSeparately,
    54 $TestSystem, $DumpAPI, $ClassListPath, $ClientPath, $StrictCompat,
    55 $DumpVersion, $BinaryOnly, $TargetTitle, %TargetVersion, $SourceOnly,
    56 $ShortMode, $KeepInternal, $OutputReportPath, $BinaryReportPath,
    57 $SourceReportPath, $Debug, $Quick, $SortDump, $SkipDeprecated, $SkipClassesList,
    58 $ShowAccess, $AffectLimit, $JdkPath, $SkipInternalPackages, $HideTemplates,
    59 $HidePackages, $ShowPackages, $Minimal, $AnnotationsListPath,
    60 $SkipPackagesList, $OutputDumpPath, $AllAffected, $Compact,
    61 $SkipAnnotationsListPath, $ExternCss, $ExternJs, $SkipInternalTypes,
    62 $AddedAnnotations, $RemovedAnnotations, $CountMethods, %DepDump, $OldStyle);
    63 
    64 my $CmdName = get_filename($0);
    65 my $OSgroup = get_OSgroup();
    66 my $ORIG_DIR = cwd();
    67 my $TMP_DIR = tempdir(CLEANUP=>1);
    68 my $ARG_MAX = get_ARG_MAX();
    69 my $REPRODUCIBLE = 1;
    70 my $MD5_LEN = 8;
    71 
    72 my %OS_Archive = (
    73     "windows"=>"zip",
    74     "default"=>"tar.gz"
    75 );
    76 
    77 my %ERROR_CODE = (
    78     # Compatible verdict
    79     "Compatible"=>0,
    80     "Success"=>0,
    81     # Incompatible verdict
    82     "Incompatible"=>1,
    83     # Undifferentiated error code
    84     "Error"=>2,
    85     # System command is not found
    86     "Not_Found"=>3,
    87     # Cannot access input files
    88     "Access_Error"=>4,
    89     # Invalid input API dump
    90     "Invalid_Dump"=>7,
    91     # Incompatible version of API dump
    92     "Dump_Version"=>8,
    93     # Cannot find a module
    94     "Module_Error"=>9
    95 );
     44
     45my $TOOL_VERSION = "2.1";
     46my $API_DUMP_VERSION = "2.1";
     47my $API_DUMP_VERSION_MIN = "2.0";
     48
     49# Internal modules
     50my $MODULES_DIR = getModules();
     51push(@INC, dirname($MODULES_DIR));
     52
     53# Basic modules
     54my %LoadedModules = ();
     55loadModule("Basic");
     56loadModule("Input");
     57loadModule("Path");
     58loadModule("Logging");
     59loadModule("Utils");
     60loadModule("TypeAttr");
     61loadModule("Filter");
     62loadModule("SysFiles");
     63loadModule("Descriptor");
     64loadModule("Mangling");
     65
     66# Rules DB
     67my %RULES_PATH = (
     68"Binary" => $MODULES_DIR."/RulesBin.xml",
     69"Source" => $MODULES_DIR."/RulesSrc.xml");
     70
     71my $CmdName = getFilename($0);
    9672
    9773my %HomePage = (
    9874    "Dev"=>"https://github.com/lvc/japi-compliance-checker",
    99     "Wiki"=>"http://ispras.linuxbase.org/index.php/Java_API_Compliance_Checker"
     75    "Doc"=>"https://lvc.github.io/japi-compliance-checker/"
    10076);
    10177
    10278my $ShortUsage = "Java API Compliance Checker (JAPICC) $TOOL_VERSION
    10379A tool for checking backward compatibility of a Java library API
    104 Copyright (C) 2016 Andrey Ponomarenko's ABI Laboratory
     80Copyright (C) 2017 Andrey Ponomarenko's ABI Laboratory
    10581License: GNU LGPL or GNU GPL
    10682
     
    11692}
    11793
    118 GetOptions("h|help!" => \$Help,
    119   "v|version!" => \$ShowVersion,
    120   "dumpversion!" => \$DumpVersion,
     94GetOptions("h|help!" => \$In::Opt{"Help"},
     95  "v|version!" => \$In::Opt{"ShowVersion"},
     96  "dumpversion!" => \$In::Opt{"DumpVersion"},
    12197# general options
    122   "l|lib|library=s" => \$TargetLibraryName,
    123   "d1|old|o=s" => \$Descriptor{1}{"Path"},
    124   "d2|new|n=s" => \$Descriptor{2}{"Path"},
     98  "l|lib|library=s" => \$In::Opt{"TargetLib"},
     99  "d1|old|o=s" => \$In::Desc{1}{"Path"},
     100  "d2|new|n=s" => \$In::Desc{2}{"Path"},
    125101# extra options
    126   "client|app=s" => \$ClientPath,
    127   "binary|bin!" => \$BinaryOnly,
    128   "source|src!" => \$SourceOnly,
    129   "v1|version1|vnum=s" => \$TargetVersion{1},
    130   "v2|version2=s" => \$TargetVersion{2},
    131   "s|strict!" => \$StrictCompat,
    132   "keep-internal!" => \$KeepInternal,
    133   "skip-internal-packages|skip-internal=s" => \$SkipInternalPackages,
    134   "skip-internal-types=s" => \$SkipInternalTypes,
    135   "dump|dump-api=s" => \$DumpAPI,
    136   "classes-list=s" => \$ClassListPath,
    137   "annotations-list=s" => \$AnnotationsListPath,
    138   "skip-annotations-list=s" => \$SkipAnnotationsListPath,
    139   "skip-deprecated!" => \$SkipDeprecated,
    140   "skip-classes=s" => \$SkipClassesList,
    141   "skip-packages=s" => \$SkipPackagesList,
    142   "short" => \$ShortMode,
    143   "dump-path=s" => \$OutputDumpPath,
    144   "report-path=s" => \$OutputReportPath,
    145   "bin-report-path=s" => \$BinaryReportPath,
    146   "src-report-path=s" => \$SourceReportPath,
    147   "quick!" => \$Quick,
    148   "sort!" => \$SortDump,
    149   "show-access!" => \$ShowAccess,
    150   "limit-affected=s" => \$AffectLimit,
    151   "hide-templates!" => \$HideTemplates,
    152   "show-packages!" => \$ShowPackages,
    153   "compact!" => \$Compact,
    154   "added-annotations!" => \$AddedAnnotations,
    155   "removed-annotations!" => \$RemovedAnnotations,
    156   "count-methods=s" => \$CountMethods,
    157   "dep1=s" => \$DepDump{1},
    158   "dep2=s" => \$DepDump{2},
    159   "old-style!" => \$OldStyle,
     102  "client|app=s" => \$In::Opt{"ClientPath"},
     103  "binary|bin!" => \$In::Opt{"BinaryOnly"},
     104  "source|src!" => \$In::Opt{"SourceOnly"},
     105  "v1|version1|vnum=s" => \$In::Desc{1}{"TargetVersion"},
     106  "v2|version2=s" => \$In::Desc{2}{"TargetVersion"},
     107  "s|strict!" => \$In::Opt{"StrictCompat"},
     108  "keep-internal!" => \$In::Opt{"KeepInternal"},
     109  "skip-internal-packages|skip-internal=s" => \$In::Opt{"SkipInternalPackages"},
     110  "skip-internal-types=s" => \$In::Opt{"SkipInternalTypes"},
     111  "dump|dump-api=s" => \$In::Opt{"DumpAPI"},
     112  "classes-list=s" => \$In::Opt{"ClassListPath"},
     113  "annotations-list=s" => \$In::Opt{"AnnotationsListPath"},
     114  "skip-annotations-list=s" => \$In::Opt{"SkipAnnotationsListPath"},
     115  "skip-deprecated!" => \$In::Opt{"SkipDeprecated"},
     116  "skip-classes=s" => \$In::Opt{"SkipClassesList"},
     117  "skip-packages=s" => \$In::Opt{"SkipPackagesList"},
     118  "short" => \$In::Opt{"ShortMode"},
     119  "dump-path=s" => \$In::Opt{"OutputDumpPath"},
     120  "report-path=s" => \$In::Opt{"OutputReportPath"},
     121  "bin-report-path=s" => \$In::Opt{"BinaryReportPath"},
     122  "src-report-path=s" => \$In::Opt{"SourceReportPath"},
     123  "quick!" => \$In::Opt{"Quick"},
     124  "sort!" => \$In::Opt{"SortDump"},
     125  "show-access!" => \$In::Opt{"ShowAccess"},
     126  "limit-affected=s" => \$In::Opt{"AffectLimit"},
     127  "hide-templates!" => \$In::Opt{"HideTemplates"},
     128  "show-packages!" => \$In::Opt{"ShowPackages"},
     129  "compact!" => \$In::Opt{"Compact"},
     130  "added-annotations!" => \$In::Opt{"AddedAnnotations"},
     131  "removed-annotations!" => \$In::Opt{"RemovedAnnotations"},
     132  "count-methods=s" => \$In::Opt{"CountMethods"},
     133  "dep1=s" => \$In::Desc{1}{"DepDump"},
     134  "dep2=s" => \$In::Desc{2}{"DepDump"},
     135  "old-style!" => \$In::Opt{"OldStyle"},
    160136# other options
    161   "test!" => \$TestSystem,
    162   "debug!" => \$Debug,
    163   "title=s" => \$TargetTitle,
    164   "jdk-path=s" => \$JdkPath,
    165   "external-css=s" => \$ExternCss,
    166   "external-js=s" => \$ExternJs,
     137  "test!" => \$In::Opt{"TestTool"},
     138  "debug!" => \$In::Opt{"Debug"},
     139  "title=s" => \$In::Opt{"TargetTitle"},
     140  "jdk-path=s" => \$In::Opt{"JdkPath"},
     141  "external-css=s" => \$In::Opt{"ExternCss"},
     142  "external-js=s" => \$In::Opt{"ExternJs"},
    167143# deprecated
    168   "minimal!" => \$Minimal,
    169   "hide-packages!" => \$HidePackages,
     144  "minimal!" => \$In::Opt{"Minimal"},
     145  "hide-packages!" => \$In::Opt{"HidePackages"},
    170146# private
    171   "all-affected!" => \$AllAffected
    172 ) or ERR_MESSAGE();
     147  "all-affected!" => \$In::Opt{"AllAffected"}
     148) or errMsg();
    173149
    174150if(@ARGV)
     
    176152    if($#ARGV==1)
    177153    { # japi-compliance-checker OLD.jar NEW.jar
    178         $Descriptor{1}{"Path"} = $ARGV[0];
    179         $Descriptor{2}{"Path"} = $ARGV[1];
     154        $In::Desc{1}{"Path"} = $ARGV[0];
     155        $In::Desc{2}{"Path"} = $ARGV[1];
    180156    }
    181157    else {
    182         ERR_MESSAGE();
    183     }
    184 }
    185 
    186 sub ERR_MESSAGE()
     158        errMsg();
     159    }
     160}
     161
     162sub errMsg()
    187163{
    188164    printMsg("INFO", "\n".$ShortUsage);
    189     exit($ERROR_CODE{"Error"});
    190 }
    191 
    192 my $AR_EXT = getAR_EXT($OSgroup);
    193 
    194 my $HelpMessage="
     165    exit(getErrorCode("Error"));
     166}
     167
     168my $HelpMessage = "
    195169NAME:
    196170  Java API Compliance Checker ($CmdName)
     
    199173DESCRIPTION:
    200174  Java API Compliance Checker (JAPICC) is a tool for checking backward
    201   binary/source compatibility of a Java library API. The tool checks classes
     175  binary/source compatibility of a Java library API. The tool checks class
    202176  declarations of old and new versions and analyzes changes that may break
    203   compatibility: removed class members, added abstract methods, etc. Breakage
    204   of the binary compatibility may result in crashing or incorrect behavior of
    205   existing clients built with an old version of a library if they run with a
    206   new one. Breakage of the source compatibility may result in recompilation
     177  compatibility: removed class members, added abstract methods, etc.
     178 
     179  Break of the binary compatibility may result in crash or incorrect behavior
     180  of existing clients built with an old library version if they run with a
     181  new one. Break of the source compatibility may result in recompilation
    207182  errors with a new library version.
    208183
    209   JAPICC is intended for library developers and operating system maintainers
    210   who are interested in ensuring backward compatibility (i.e. allow old clients
    211   to run or to be recompiled with a new version of a library).
     184  The tool is intended for developers of software libraries and maintainers
     185  of operating systems who are interested in ensuring backward compatibility,
     186  i.e. allow old clients to run or to be recompiled with newer library
     187  versions.
    212188
    213189  This tool is free software: you can redistribute it and/or modify it
     
    217193  $CmdName [options]
    218194
    219 EXAMPLE:
     195EXAMPLE 1:
    220196  $CmdName OLD.jar NEW.jar
    221     OR
     197
     198EXAMPLE 2:
    222199  $CmdName -lib NAME -old OLD.xml -new NEW.xml
    223200  OLD.xml and NEW.xml are XML-descriptors:
     
    244221
    245222GENERAL OPTIONS:
    246   -l|-lib|-library NAME
     223  -l|-library NAME
    247224      Library name (without version).
    248225
    249   -d1|-old|-o PATH
    250       Descriptor of 1st (old) library version.
     226  -old|-d1 PATH
     227      Descriptor of the 1st (old) library version.
    251228      It may be one of the following:
    252229     
    253          1. Java ARchive (*.jar)
     230         1. Java archive (*.jar)
    254231         2. XML-descriptor (VERSION.xml file):
    255232
     
    268245         3. API dump generated by -dump option
    269246
    270       If you are using 1, 4-6 descriptor types then you should
     247      If you are using *.jar as a descriptor then you should
    271248      specify version numbers with -v1 and -v2 options too.
    272 
    273       If you are using *.jar as a descriptor then the tool will try to
    274       get implementation version from MANIFEST.MF file.
    275 
    276   -d2|-new|-n PATH
    277       Descriptor of 2nd (new) library version.
     249      If version numbers are not specified then the tool will
     250      try to detect them automatically.
     251
     252  -new|-d2 PATH
     253      Descriptor of the 2nd (new) library version.
    278254
    279255EXTRA OPTIONS:
    280256  -client|-app PATH
    281       This option allows to specify the client Java ARchive that should be
     257      This option allows to specify the client Java archive that should be
    282258      checked for portability to the new library version.
    283      
     259
    284260  -binary|-bin
    285261      Show \"Binary\" compatibility problems only.
    286262      Generate report to \"bin_compat_report.html\".
    287      
     263
    288264  -source|-src
    289265      Show \"Source\" compatibility problems only.
    290266      Generate report to \"src_compat_report.html\".
    291      
     267
    292268  -v1|-version1 NUM
    293269      Specify 1st API version outside the descriptor. This option is needed
     
    323299      Dump library API to gzipped TXT format file. You can transfer it
    324300      anywhere and pass instead of the descriptor. Also it may be used
    325       for debugging the tool. Compatible dump versions: $API_DUMP_MAJOR.0<=V<=$API_DUMP_VERSION
     301      for debugging the tool.
    326302     
    327303  -classes-list PATH
     
    352328 
    353329  -dump-path PATH
    354       Specify a *.api.$AR_EXT or *.api file path where to generate an API dump.
     330      Specify a *.dump file path where to generate an API dump.
    355331      Default:
    356           abi_dumps/LIB_NAME/LIB_NAME_VERSION.api.$AR_EXT
     332          api_dumps/LIB_NAME/VERSION/API.dump
    357333
    358334  -report-path PATH
     
    455431    non-zero - Incompatible or the tool has run with errors.
    456432
    457 MORE INFORMATION:
    458     ".$HomePage{"Wiki"}."
    459     ".$HomePage{"Dev"}."\n\n";
    460 
    461 sub HELP_MESSAGE()
    462 { # -help
     433MORE INFO:
     434    ".$HomePage{"Doc"}."
     435    ".$HomePage{"Dev"};
     436
     437sub helpMsg() {
    463438    printMsg("INFO", $HelpMessage."\n");
    464439}
    465440
    466 my %TypeProblems_Kind=(
    467     "Binary"=>{
    468         "NonAbstract_Class_Added_Abstract_Method"=>"High",
    469         "Abstract_Class_Added_Abstract_Method"=>"Safe",
    470         "Abstract_Class_Added_Abstract_Method_Invoked_By_Others"=>"Medium",
    471         "Class_Removed_Abstract_Method"=>"High",
    472         "Interface_Added_Abstract_Method"=>"Safe",
    473         "Interface_Added_Abstract_Method_Invoked_By_Others"=>"Medium",
    474         "Interface_Removed_Abstract_Method"=>"High",
    475         "Removed_Class"=>"High",
    476         "Removed_Interface"=>"High",
    477         "Class_Method_Became_Abstract"=>"High",
    478         "Class_Method_Became_NonAbstract"=>"Low",
    479         "Interface_Method_Became_NonDefault"=>"High",
    480         "Interface_Method_Became_Default"=>"Safe",
    481         "Added_Super_Class"=>"Low",
    482         "Abstract_Class_Added_Super_Abstract_Class"=>"Safe",
    483         "Abstract_Class_Added_Super_Abstract_Class_Invoked_By_Others"=>"Medium",
    484         "Removed_Super_Class"=>"Medium",
    485         "Changed_Super_Class"=>"Medium",
    486         "Abstract_Class_Added_Super_Interface"=>"Safe",
    487         "Abstract_Class_Added_Super_Interface_Invoked_By_Others"=>"Medium",
    488         "Abstract_Class_Added_Super_Interface_With_Implemented_Methods"=>"Safe",
    489         "Class_Removed_Super_Interface"=>"High",
    490         "Interface_Added_Super_Interface"=>"Safe",
    491         "Interface_Added_Super_Interface_Used_By_Others"=>"Medium",
    492         "Interface_Added_Super_Constant_Interface"=>"Low",
    493         "Interface_Added_Super_Interface_With_Implemented_Methods"=>"Safe",
    494         "Interface_Removed_Super_Interface"=>"High",
    495         "Interface_Removed_Super_Constant_Interface"=>"Safe",
    496         "Class_Became_Interface"=>"High",
    497         "Interface_Became_Class"=>"High",
    498         "Class_Became_Final"=>"High",
    499         "Class_Became_Abstract"=>"High",
    500         "Class_Added_Field"=>"Safe",
    501         "Interface_Added_Field"=>"Safe",
    502         "Removed_NonConstant_Field"=>"High",
    503         "Removed_Constant_Field"=>"Low",
    504         "Renamed_Field"=>"High",
    505         "Renamed_Constant_Field"=>"Low",
    506         "Changed_Field_Type"=>"High",
    507         "Changed_Field_Access"=>"High",
    508         "Changed_Final_Field_Value"=>"Medium",
    509         "Changed_Final_Version_Field_Value"=>"Low",
    510         "Field_Became_Final"=>"Medium",
    511         "Field_Became_NonFinal"=>"Low",
    512         "NonConstant_Field_Became_Static"=>"High",
    513         "NonConstant_Field_Became_NonStatic"=>"High",
    514         "Class_Overridden_Method"=>"Low",
    515         "Class_Method_Moved_Up_Hierarchy"=>"Low"
    516     },
    517     "Source"=>{
    518         "NonAbstract_Class_Added_Abstract_Method"=>"High",
    519         "Abstract_Class_Added_Abstract_Method"=>"High",
    520         "Abstract_Class_Added_Abstract_Method_Invoked_By_Others"=>"High",
    521         "Interface_Added_Abstract_Method"=>"High",
    522         "Interface_Added_Abstract_Method_Invoked_By_Others"=>"High",
    523         "Class_Removed_Abstract_Method"=>"High",
    524         "Interface_Removed_Abstract_Method"=>"High",
    525         "Removed_Class"=>"High",
    526         "Removed_Interface"=>"High",
    527         "Class_Method_Became_Abstract"=>"High",
    528         "Class_Method_Became_NonAbstract"=>"Safe",
    529         "Interface_Method_Became_NonDefault"=>"High",
    530         "Interface_Method_Became_Default"=>"Safe",
    531         "Added_Super_Class"=>"Low",
    532         "Abstract_Class_Added_Super_Abstract_Class"=>"High",
    533         "Abstract_Class_Added_Super_Abstract_Class_Invoked_By_Others"=>"High",
    534         "Removed_Super_Class"=>"Medium",
    535         "Changed_Super_Class"=>"Medium",
    536         "Abstract_Class_Added_Super_Interface"=>"High",
    537         "Abstract_Class_Added_Super_Interface_Invoked_By_Others"=>"High",
    538         "Abstract_Class_Added_Super_Interface_With_Implemented_Methods"=>"Safe",
    539         "Class_Removed_Super_Interface"=>"High",
    540         "Interface_Added_Super_Interface"=>"High",
    541         "Interface_Added_Super_Interface_Used_By_Others"=>"High",
    542         "Interface_Added_Super_Constant_Interface"=>"Low",
    543         "Interface_Added_Super_Interface_With_Implemented_Methods"=>"Safe",
    544         "Interface_Removed_Super_Interface"=>"High",
    545         "Interface_Removed_Super_Constant_Interface"=>"High",
    546         "Class_Became_Interface"=>"High",
    547         "Interface_Became_Class"=>"High",
    548         "Class_Became_Final"=>"High",
    549         "Class_Became_Abstract"=>"High",
    550         "Class_Added_Field"=>"Safe",
    551         "Interface_Added_Field"=>"Safe",
    552         "Removed_NonConstant_Field"=>"High",
    553         "Removed_Constant_Field"=>"High",
    554         "Renamed_Field"=>"High",
    555         "Renamed_Constant_Field"=>"High",
    556         "Changed_Field_Type"=>"High",
    557         "Changed_Field_Access"=>"High",
    558         "Field_Became_Final"=>"Medium",
    559         "Constant_Field_Became_NonStatic"=>"High",
    560         "NonConstant_Field_Became_NonStatic"=>"High",
    561         "Removed_Annotation"=>"High"
    562     }
    563 );
    564 
    565 my %MethodProblems_Kind=(
    566     "Binary"=>{
    567         "Added_Method"=>"Safe",
    568         "Removed_Method"=>"High",
    569         "Method_Became_Static"=>"High",
    570         "Method_Became_NonStatic"=>"High",
    571         "NonStatic_Method_Became_Final"=>"Medium",
    572         "Changed_Method_Access"=>"High",
    573         "Method_Became_Synchronized"=>"Low",
    574         "Method_Became_NonSynchronized"=>"Low",
    575         "Method_Became_Abstract"=>"High",
    576         "Method_Became_NonAbstract"=>"Low",
    577         "Method_Became_NonDefault"=>"High",
    578         "Method_Became_Default"=>"Safe",
    579         "NonAbstract_Method_Added_Checked_Exception"=>"Low",
    580         "NonAbstract_Method_Removed_Checked_Exception"=>"Low",
    581         "Added_Unchecked_Exception"=>"Low",
    582         "Removed_Unchecked_Exception"=>"Low",
    583         "Variable_Arity_To_Array"=>"Low",# not implemented yet
    584         "Changed_Method_Return_From_Void"=>"High"
    585     },
    586     "Source"=>{
    587         "Added_Method"=>"Safe",
    588         "Removed_Method"=>"High",
    589         "Method_Became_Static"=>"Low",
    590         "Method_Became_NonStatic"=>"High",
    591         "Static_Method_Became_Final"=>"Medium",
    592         "NonStatic_Method_Became_Final"=>"Medium",
    593         "Changed_Method_Access"=>"High",
    594         "Method_Became_Abstract"=>"High",
    595         "Method_Became_NonAbstract"=>"Safe",
    596         "Method_Became_NonDefault"=>"High",
    597         "Method_Became_Default"=>"Safe",
    598         "Abstract_Method_Added_Checked_Exception"=>"Medium",
    599         "NonAbstract_Method_Added_Checked_Exception"=>"Medium",
    600         "Abstract_Method_Removed_Checked_Exception"=>"Medium",
    601         "NonAbstract_Method_Removed_Checked_Exception"=>"Medium"
    602     }
    603 );
    604 
     441#Aliases
     442my (%MethodInfo, %TypeInfo, %TName_Tid) = ();
     443
     444#Separate checked and unchecked exceptions
    605445my %KnownRuntimeExceptions= map {$_=>1} (
    606 # To separate checked- and unchecked- exceptions
    607446    "java.lang.AnnotationTypeMismatchException",
    608447    "java.lang.ArithmeticException",
     
    656495);
    657496
    658 my %Slash_Type=(
    659     "default"=>"/",
    660     "windows"=>"\\"
    661 );
    662 
    663 my $SLASH = $Slash_Type{$OSgroup}?$Slash_Type{$OSgroup}:$Slash_Type{"default"};
    664 
    665 my %OS_AddPath=(
    666 # this data needed if tool can't detect it automatically
    667 "macos"=>{
    668     "bin"=>{"/Developer/usr/bin"=>1}},
    669 "beos"=>{
    670     "bin"=>{"/boot/common/bin"=>1,"/boot/system/bin"=>1,"/boot/develop/abi"=>1}}
    671 );
    672 
    673 #Global variables
    674 my %RESULT;
    675 my $ExtractCounter = 0;
    676 my %Cache;
    677 my $TOP_REF = "<a class='top_ref' href='#Top'>to the top</a>";
    678 my %DEBUG_PATH;
    679 
    680 #Types
    681 my %TypeInfo;
    682 my $TYPE_ID = 0;
    683 my %CheckedTypes;
    684 my %TName_Tid;
    685 my %Class_Constructed;
    686 
    687 #Classes
    688 my %ClassList_User;
    689 my %UsedMethods_Client;
    690 my %UsedFields_Client;
    691 my %UsedClasses_Client;
    692 my %LibArchives;
    693 my %Class_Methods;
    694 my %Class_AbstractMethods;
    695 my %Class_Fields;
    696 my %MethodUsed;
    697 my %ClassMethod_AddedUsed;
    698 # my %FieldUsed;
    699 
    700497#java.lang.Object
    701498my %JavaObjectMethod = (
     
    714511);
    715512
    716 #Annotations
    717 my %AnnotationList_User;
    718 my %SkipAnnotationList_User;
     513#Global variables
     514my %Cache;
     515my %RESULT;
     516my $TOP_REF = "<a class='top_ref' href='#Top'>to the top</a>";
     517
     518#Types
     519my %CheckedTypes;
     520
     521#Classes
     522my %LibArchives;
     523my %Class_Methods;
     524my %Class_AbstractMethods;
     525my %Class_Fields;
     526my %ClassMethod_AddedUsed;
     527my %Class_Constructed;
    719528
    720529#Methods
    721530my %CheckedMethods;
    722 my %tr_name;
     531my %MethodUsed;
    723532
    724533#Merging
    725 my %MethodInfo;
    726 my $Version;
    727534my %AddedMethod_Abstract;
    728535my %RemovedMethod_Abstract;
    729536my %ChangedReturnFromVoid;
    730 my %SkipClasses;
    731 my %SkipPackages;
    732 my %KeepPackages;
    733 my %SkippedPackage;
     537my %CompatRules;
     538my %IncompleteRules;
    734539
    735540#Report
     
    737542
    738543#Recursion locks
    739 my @RecurSymlink;
    740544my @RecurTypes;
    741 
    742 #System
    743 my %SystemPaths;
    744 my %DefaultBinPaths;
    745545
    746546#Problem descriptions
     
    760560my $Content_Counter = 0;
    761561
    762 #Modes
    763 my $JoinReport = 1;
    764 my $DoubleReport = 0;
    765 
    766 sub get_CmdPath($)
     562sub getModules()
     563{
     564    my $TOOL_DIR = dirname($0);
     565    if(not $TOOL_DIR)
     566    { # patch for MS Windows
     567        $TOOL_DIR = ".";
     568    }
     569    my @SEARCH_DIRS = (
     570        # tool's directory
     571        abs_path($TOOL_DIR),
     572        # relative path to modules
     573        abs_path($TOOL_DIR)."/../share/japi-compliance-checker",
     574        # install path
     575        'MODULES_INSTALL_PATH'
     576    );
     577    foreach my $DIR (@SEARCH_DIRS)
     578    {
     579        if($DIR!~/\A(\/|\w+:[\/\\])/)
     580        { # relative path
     581            $DIR = abs_path($TOOL_DIR)."/".$DIR;
     582        }
     583        if(-d $DIR."/modules") {
     584            return $DIR."/modules";
     585        }
     586    }
     587   
     588    print STDERR "ERROR: can't find modules (Did you installed the tool by 'make install' command?)\n";
     589    exit(9); # Module_Error
     590}
     591
     592sub loadModule($)
    767593{
    768594    my $Name = $_[0];
    769     return "" if(not $Name);
    770     if(defined $Cache{"get_CmdPath"}{$Name}) {
    771         return $Cache{"get_CmdPath"}{$Name};
    772     }
    773     my $Path = search_Cmd($Name);
    774     if(not $Path and $OSgroup eq "windows")
    775     { # search for *.exe file
    776         $Path=search_Cmd($Name.".exe");
    777     }
    778     if (not $Path) {
    779         $Path=search_Cmd_Path($Name);
    780     }
    781     if($Path=~/\s/) {
    782         $Path = "\"".$Path."\"";
    783     }
    784     return ($Cache{"get_CmdPath"}{$Name} = $Path);
    785 }
    786 
    787 sub search_Cmd($)
    788 {
    789     my $Name = $_[0];
    790     return "" if(not $Name);
    791     if(defined $Cache{"search_Cmd"}{$Name}) {
    792         return $Cache{"search_Cmd"}{$Name};
    793     }
    794     if(defined $JdkPath)
    795     {
    796         if(-x $JdkPath."/".$Name) {
    797             return ($Cache{"search_Cmd"}{$Name} = $JdkPath."/".$Name);
    798         }
    799        
    800         if(-x $JdkPath."/bin/".$Name) {
    801             return ($Cache{"search_Cmd"}{$Name} = $JdkPath."/bin/".$Name);
    802         }
    803     }
    804     if(my $DefaultPath = get_CmdPath_Default($Name)) {
    805         return ($Cache{"search_Cmd"}{$Name} = $DefaultPath);
    806     }
    807     return ($Cache{"search_Cmd"}{$Name} = "");
    808 }
    809 
    810 sub search_Cmd_Path($)
    811 {
    812     my $Name = $_[0];
    813     return "" if(not $Name);
    814    
    815     if(defined $Cache{"search_Cmd_Path"}{$Name}) {
    816         return $Cache{"search_Cmd_Path"}{$Name};
    817     }
    818    
    819     if(defined $SystemPaths{"bin"})
    820     {
    821         foreach my $Path (sort {length($a)<=>length($b)} keys(%{$SystemPaths{"bin"}}))
    822         {
    823             if(-f $Path."/".$Name or -f $Path."/".$Name.".exe") {
    824                 return ($Cache{"search_Cmd_Path"}{$Name} = joinPath($Path,$Name));
    825             }
    826         }
    827     }
    828 
    829     return ($Cache{"search_Cmd_Path"}{$Name} = "");
    830 }
    831 
    832 sub get_CmdPath_Default($)
    833 { # search in PATH
    834     return "" if(not $_[0]);
    835     if(defined $Cache{"get_CmdPath_Default"}{$_[0]}) {
    836         return $Cache{"get_CmdPath_Default"}{$_[0]};
    837     }
    838     return ($Cache{"get_CmdPath_Default"}{$_[0]} = get_CmdPath_Default_I($_[0]));
    839 }
    840 
    841 sub get_CmdPath_Default_I($)
    842 { # search in PATH
    843     my $Name = $_[0];
    844     if($Name=~/find/)
    845     { # special case: search for "find" utility
    846         if(`find \"$TMP_DIR\" -maxdepth 0 2>\"$TMP_DIR/null\"`) {
    847             return "find";
    848         }
    849     }
    850     if(get_version($Name)) {
    851         return $Name;
    852     }
    853     if($OSgroup eq "windows")
    854     {
    855         if(`$Name /? 2>\"$TMP_DIR/null\"`) {
    856             return $Name;
    857         }
    858     }
    859     if($Name!~/which/)
    860     {
    861         if(my $WhichCmd = get_CmdPath("which"))
    862         {
    863             if(`$WhichCmd $Name 2>\"$TMP_DIR/null\"`) {
    864                 return $Name;
    865             }
    866         }
    867     }
    868     foreach my $Path (sort {length($a)<=>length($b)} keys(%DefaultBinPaths))
    869     {
    870         if(-f $Path."/".$Name) {
    871             return joinPath($Path,$Name);
    872         }
    873     }
    874     return "";
    875 }
    876 
    877 sub showPos($)
    878 {
    879     my $Number = $_[0];
    880     if(not $Number) {
    881         $Number = 1;
    882     }
    883     else {
    884         $Number = int($Number)+1;
    885     }
    886     if($Number>3) {
    887         return $Number."th";
    888     }
    889     elsif($Number==1) {
    890         return "1st";
    891     }
    892     elsif($Number==2) {
    893         return "2nd";
    894     }
    895     elsif($Number==3) {
    896         return "3rd";
    897     }
    898     else {
    899         return $Number;
    900     }
    901 }
    902 
    903 sub getAR_EXT($)
    904 {
    905     my $Target = $_[0];
    906     if(my $Ext = $OS_Archive{$Target}) {
    907         return $Ext;
    908     }
    909     return $OS_Archive{"default"};
    910 }
    911 
    912 sub readDescriptor($$)
    913 {
    914     my ($LibVersion, $Content) = @_;
    915     return if(not $LibVersion);
    916     my $DName = $DumpAPI?"descriptor":"descriptor \"d$LibVersion\"";
    917     if(not $Content) {
    918         exitStatus("Error", "$DName is empty");
    919     }
    920     if($Content!~/\</) {
    921         exitStatus("Error", "descriptor should be one of the following:\n  Java ARchive, XML descriptor, gzipped API dump or directory with Java ARchives.");
    922     }
    923     $Content=~s/\/\*(.|\n)+?\*\///g;
    924     $Content=~s/<\!--(.|\n)+?-->//g;
    925     $Descriptor{$LibVersion}{"Version"} = parseTag(\$Content, "version");
    926     $Descriptor{$LibVersion}{"Version"} = $TargetVersion{$LibVersion} if($TargetVersion{$LibVersion});
    927     if($Descriptor{$LibVersion}{"Version"} eq "") {
    928         exitStatus("Error", "version in the $DName is not specified (<version> section)");
    929     }
    930    
    931     my $DArchives = parseTag(\$Content, "archives");
    932     if(not $DArchives){
    933         exitStatus("Error", "Java ARchives in the $DName are not specified (<archive> section)");
    934     }
    935     else
    936     {# append the descriptor Java ARchives list
    937         if($Descriptor{$LibVersion}{"Archives"}) {
    938             $Descriptor{$LibVersion}{"Archives"} .= "\n".$DArchives;
    939         }
    940         else {
    941             $Descriptor{$LibVersion}{"Archives"} = $DArchives;
    942         }
    943         foreach my $Path (split(/\s*\n\s*/, $DArchives))
    944         {
    945             if(not -e $Path) {
    946                 exitStatus("Access_Error", "can't access \'$Path\'");
    947             }
    948         }
    949     }
    950     foreach my $Package (split(/\s*\n\s*/, parseTag(\$Content, "skip_packages"))) {
    951         $SkipPackages{$LibVersion}{$Package} = 1;
    952     }
    953     foreach my $Package (split(/\s*\n\s*/, parseTag(\$Content, "packages"))) {
    954         $KeepPackages{$LibVersion}{$Package} = 1;
    955     }
    956 }
    957 
    958 sub parseTag($$)
    959 {
    960     my ($CodeRef, $Tag) = @_;
    961     return "" if(not $CodeRef or not ${$CodeRef} or not $Tag);
    962     if(${$CodeRef}=~s/\<\Q$Tag\E\>((.|\n)+?)\<\/\Q$Tag\E\>//)
    963     {
    964         my $Content = $1;
    965         $Content=~s/(\A\s+|\s+\Z)//g;
    966         return $Content;
    967     }
    968     else {
    969         return "";
    970     }
    971 }
    972 
    973 sub ignore_path($$)
    974 {
    975     my ($Path, $Prefix) = @_;
    976     return 1 if(not $Path or not -e $Path
    977     or not $Prefix or not -e $Prefix);
    978     return 1 if($Path=~/\~\Z/);# skipping system backup files
    979     # skipping hidden .svn, .git, .bzr, .hg and CVS directories
    980     return 1 if(cut_path_prefix($Path, $Prefix)=~/(\A|[\/\\]+)(\.(svn|git|bzr|hg)|CVS)([\/\\]+|\Z)/);
    981     return 0;
    982 }
    983 
    984 sub cut_path_prefix($$)
    985 {
    986     my ($Path, $Prefix) = @_;
    987     $Prefix=~s/[\/\\]+\Z//;
    988     $Path=~s/\A\Q$Prefix\E([\/\\]+|\Z)//;
    989     return $Path;
    990 }
    991 
    992 sub get_filename($)
    993 { # much faster than basename() from File::Basename module
    994     if(defined $Cache{"get_filename"}{$_[0]}) {
    995         return $Cache{"get_filename"}{$_[0]};
    996     }
    997     if($_[0] and $_[0]=~/([^\/\\]+)[\/\\]*\Z/) {
    998         return ($Cache{"get_filename"}{$_[0]}=$1);
    999     }
    1000     return ($Cache{"get_filename"}{$_[0]}="");
    1001 }
    1002 
    1003 sub get_dirname($)
    1004 { # much faster than dirname() from File::Basename module
    1005     if(defined $Cache{"get_dirname"}{$_[0]}) {
    1006         return $Cache{"get_dirname"}{$_[0]};
    1007     }
    1008     if($_[0] and $_[0]=~/\A(.*?)[\/\\]+[^\/\\]*[\/\\]*\Z/) {
    1009         return ($Cache{"get_dirname"}{$_[0]}=$1);
    1010     }
    1011     return ($Cache{"get_dirname"}{$_[0]}="");
    1012 }
    1013 
    1014 sub separate_path($) {
    1015     return (get_dirname($_[0]), get_filename($_[0]));
    1016 }
    1017 
    1018 sub joinPath($$)
    1019 {
    1020     return join($SLASH, @_);
    1021 }
    1022 
    1023 sub get_abs_path($)
    1024 { # abs_path() should NOT be called for absolute inputs
    1025   # because it can change them
    1026     my $Path = $_[0];
    1027     if(not is_abs($Path)) {
    1028         $Path = abs_path($Path);
    1029     }
    1030     return $Path;
    1031 }
    1032 
    1033 sub is_abs($) {
    1034     return ($_[0]=~/\A(\/|\w+:[\/\\])/);
    1035 }
    1036 
    1037 sub cmd_find($$$$)
    1038 {
    1039     my ($Path, $Type, $Name, $MaxDepth) = @_;
    1040     return () if(not $Path or not -e $Path);
    1041     if($OSgroup eq "windows")
    1042     {
    1043         my $DirCmd = get_CmdPath("dir");
    1044         if(not $DirCmd) {
    1045             exitStatus("Not_Found", "can't find \"dir\" command");
    1046         }
    1047         $Path=~s/[\\]+\Z//;
    1048         $Path = get_abs_path($Path);
    1049         my $Cmd = $DirCmd." \"$Path\" /B /O";
    1050         if($MaxDepth!=1) {
    1051             $Cmd .= " /S";
    1052         }
    1053         if($Type eq "d") {
    1054             $Cmd .= " /AD";
    1055         }
    1056         my @Files = ();
    1057         if($Name)
    1058         { # FIXME: how to search file names in MS shell?
    1059             $Name=~s/\*/.*/g if($Name!~/\]/);
    1060             foreach my $File (split(/\n/, `$Cmd`))
    1061             {
    1062                 if($File=~/$Name\Z/i) {
    1063                     push(@Files, $File);   
    1064                 }
    1065             }
    1066         }
    1067         else {
    1068             @Files = split(/\n/, `$Cmd 2>\"$TMP_DIR/null\"`);
    1069         }
    1070         my @AbsPaths = ();
    1071         foreach my $File (@Files)
    1072         {
    1073             if(not is_abs($File)) {
    1074                 $File = joinPath($Path, $File);
    1075             }
    1076             if($Type eq "f" and not -f $File)
    1077             { # skip dirs
    1078                 next;
    1079             }
    1080             push(@AbsPaths, $File);
    1081         }
    1082         if($Type eq "d") {
    1083             push(@AbsPaths, $Path);
    1084         }
    1085         return @AbsPaths;
    1086     }
    1087     else
    1088     {
    1089         my $FindCmd = get_CmdPath("find");
    1090         if(not $FindCmd) {
    1091             exitStatus("Not_Found", "can't find a \"find\" command");
    1092         }
    1093         $Path = get_abs_path($Path);
    1094         if(-d $Path and -l $Path
    1095         and $Path!~/\/\Z/)
    1096         { # for directories that are symlinks
    1097             $Path.="/";
    1098         }
    1099         my $Cmd = $FindCmd." \"$Path\"";
    1100         if($MaxDepth) {
    1101             $Cmd .= " -maxdepth $MaxDepth";
    1102         }
    1103         if($Type) {
    1104             $Cmd .= " -type $Type";
    1105         }
    1106         if($Name)
    1107         {
    1108             if($Name=~/\]/) {
    1109                 $Cmd .= " -regex \"$Name\"";
    1110             }
    1111             else {
    1112                 $Cmd .= " -name \"$Name\"";
    1113             }
    1114         }
    1115         return split(/\n/, `$Cmd 2>\"$TMP_DIR/null\"`);
    1116     }
    1117 }
    1118 
    1119 sub path_format($$)
    1120 { # forward slash to pass into MinGW GCC
    1121     my ($Path, $Fmt) = @_;
    1122     if($Fmt eq "windows")
    1123     {
    1124         $Path=~s/\//\\/g;
    1125         $Path=lc($Path);
    1126     }
    1127     else {
    1128         $Path=~s/\\/\//g;
    1129     }
    1130     return $Path;
    1131 }
    1132 
    1133 sub unpackDump($)
    1134 {
    1135     my $Path = $_[0];
    1136     return "" if(not $Path or not -e $Path);
    1137    
    1138     if(isDumpFile($Path)) {
    1139         return $Path;
    1140     }
    1141    
    1142     $Path = get_abs_path($Path);
    1143     $Path = path_format($Path, $OSgroup);
    1144     my ($Dir, $FileName) = separate_path($Path);
    1145     my $UnpackDir = $TMP_DIR."/unpack";
    1146     if(-d $UnpackDir) {
    1147         rmtree($UnpackDir);
    1148     }
    1149     mkpath($UnpackDir);
    1150     if($FileName=~s/\Q.zip\E\Z//g)
    1151     { # *.zip
    1152         my $UnzipCmd = get_CmdPath("unzip");
    1153         if(not $UnzipCmd) {
    1154             exitStatus("Not_Found", "can't find \"unzip\" command");
    1155         }
    1156         chdir($UnpackDir);
    1157         system("$UnzipCmd \"$Path\" >contents.txt");
    1158         if($?) {
    1159             exitStatus("Error", "can't extract \'$Path\'");
    1160         }
    1161         chdir($ORIG_DIR);
    1162         my @Contents = ();
    1163         foreach (split("\n", readFile("$UnpackDir/contents.txt")))
    1164         {
    1165             if(/inflating:\s*([^\s]+)/) {
    1166                 push(@Contents, $1);
    1167             }
    1168         }
    1169         if(not @Contents) {
    1170             exitStatus("Error", "can't extract \'$Path\'");
    1171         }
    1172         return joinPath($UnpackDir, $Contents[0]);
    1173     }
    1174     elsif($FileName=~s/\Q.tar.gz\E\Z//g)
    1175     { # *.tar.gz
    1176         if($OSgroup eq "windows")
    1177         { # -xvzf option is not implemented in tar.exe (2003)
    1178           # use "gzip.exe -k -d -f" + "tar.exe -xvf" instead
    1179             my $TarCmd = get_CmdPath("tar");
    1180             if(not $TarCmd) {
    1181                 exitStatus("Not_Found", "can't find \"tar\" command");
    1182             }
    1183             my $GzipCmd = get_CmdPath("gzip");
    1184             if(not $GzipCmd) {
    1185                 exitStatus("Not_Found", "can't find \"gzip\" command");
    1186             }
    1187             chdir($UnpackDir);
    1188             qx/$GzipCmd -k -d -f "$Path"/; # keep input files (-k)
    1189             if($?) {
    1190                 exitStatus("Error", "can't extract \'$Path\'");
    1191             }
    1192             my @Contents = qx/$TarCmd -xvf "$Dir\\$FileName.tar"/;
    1193             if($? or not @Contents) {
    1194                 exitStatus("Error", "can't extract \'$Path\'");
    1195             }
    1196             chdir($ORIG_DIR);
    1197             unlink($Dir."/".$FileName.".tar");
    1198             chomp $Contents[0];
    1199             return joinPath($UnpackDir, $Contents[0]);
    1200         }
    1201         else
    1202         { # Linux, Unix, OS X
    1203             my $TarCmd = get_CmdPath("tar");
    1204             if(not $TarCmd) {
    1205                 exitStatus("Not_Found", "can't find \"tar\" command");
    1206             }
    1207             chdir($UnpackDir);
    1208             my @Contents = qx/$TarCmd -xvzf "$Path" 2>&1/;
    1209             if($? or not @Contents) {
    1210                 exitStatus("Error", "can't extract \'$Path\'");
    1211             }
    1212             chdir($ORIG_DIR);
    1213             $Contents[0]=~s/^x //; # OS X
    1214             chomp $Contents[0];
    1215             return joinPath($UnpackDir, $Contents[0]);
    1216         }
    1217     }
     595    if(defined $LoadedModules{$Name}) {
     596        return;
     597    }
     598    my $Path = $MODULES_DIR."/Internals/$Name.pm";
     599    if(not -f $Path)
     600    {
     601        print STDERR "can't access \'$Path\'\n";
     602        exit(2);
     603    }
     604    require $Path;
     605    $LoadedModules{$Name} = 1;
     606}
     607
     608sub readModule($$)
     609{
     610    my ($Module, $Name) = @_;
     611    my $Path = $MODULES_DIR."/Internals/$Module/".$Name;
     612    if(not -f $Path) {
     613        exitStatus("Module_Error", "can't access \'$Path\'");
     614    }
     615    return readFile($Path);
    1218616}
    1219617
     
    1225623    {
    1226624        next if(not $ClassName);
    1227         my $Type1_Id = $TName_Tid{1}{$ClassName};
    1228         my %Type1 = get_Type($Type1_Id, 1);
    1229        
    1230         if($Type1{"Type"}!~/class|interface/) {
     625        my $Type1 = getType($TName_Tid{1}{$ClassName}, 1);
     626       
     627        if($Type1->{"Type"}!~/class|interface/) {
    1231628            next;
    1232629        }
    1233630       
    1234         if(defined $Type1{"Access"}
    1235         and $Type1{"Access"}=~/private/) {
     631        if(defined $Type1->{"Access"}
     632        and $Type1->{"Access"}=~/private/) {
    1236633            next;
    1237634        }
    1238635       
    1239         if(not classFilter(\%Type1, 1, 0)) {
     636        if(not classFilter($Type1, 1, 0)) {
    1240637            next;
    1241638        }
     
    1253650                $CheckedMethods{$Method} = 1;
    1254651               
    1255                 if($Type1{"Type"} eq "class")
     652                if($Type1->{"Type"} eq "class")
    1256653                {
    1257654                    %{$CompatProblems{$Method}{"Removed_Class"}{"this"}} = (
    1258655                        "Type_Name"=>$ClassName,
    1259                         "Target"=>$ClassName  );
     656                        "Target"=>$ClassName);
    1260657                }
    1261658                else
     
    1263660                    %{$CompatProblems{$Method}{"Removed_Interface"}{"this"}} = (
    1264661                        "Type_Name"=>$ClassName,
    1265                         "Target"=>$ClassName  );
     662                        "Target"=>$ClassName);
    1266663                }
    1267664               
     
    1273670    foreach my $Class_Id (keys(%{$TypeInfo{1}}))
    1274671    {
    1275         my %Class1 = get_Type($Class_Id, 1);
    1276        
    1277         if($Class1{"Type"}!~/class|interface/) {
     672        my $Class1 = getType($Class_Id, 1);
     673       
     674        if($Class1->{"Type"}!~/class|interface/) {
    1278675            next;
    1279676        }
    1280677       
    1281         if(defined $Class1{"Access"}
    1282         and $Class1{"Access"}=~/private/) {
     678        if(defined $Class1->{"Access"}
     679        and $Class1->{"Access"}=~/private/) {
    1283680            next;
    1284681        }
    1285682       
    1286         if(not classFilter(\%Class1, 1, 1)) {
     683        if(not classFilter($Class1, 1, 1)) {
    1287684            next;
    1288685        }
    1289686       
    1290         my $ClassName = $Class1{"Name"};
     687        my $ClassName = $Class1->{"Name"};
    1291688       
    1292689        if(my $Class2_Id = $TName_Tid{2}{$ClassName})
     
    1294691            if(not defined $Class_Methods{1}{$ClassName})
    1295692            {
    1296                 my %Class2 = get_Type($Class2_Id, 2);
     693                my $Class2 = getType($Class2_Id, 2);
    1297694               
    1298                 foreach my $Field (keys(%{$Class1{"Fields"}}))
     695                foreach my $Field (keys(%{$Class1->{"Fields"}}))
    1299696                {
    1300                     my $FieldInfo = $Class1{"Fields"}{$Field};
     697                    my $FieldInfo = $Class1->{"Fields"}{$Field};
    1301698                   
    1302699                    my $FAccess = $FieldInfo->{"Access"};
     
    1309706                        $CheckedTypes{$ClassName} = 1;
    1310707                       
    1311                         if(not defined $Class2{"Fields"}{$Field})
     708                        if(not defined $Class2->{"Fields"}{$Field})
    1312709                        {
    1313710                            %{$CompatProblems{".client_method"}{"Removed_NonConstant_Field"}{$Field}}=(
    1314711                                "Target"=>$Field,
    1315712                                "Type_Name"=>$ClassName,
    1316                                 "Type_Type"=>$Class1{"Type"},
    1317                                 "Field_Type"=>get_TypeName($FieldInfo->{"Type"}, 1)  );
     713                                "Type_Type"=>$Class1->{"Type"},
     714                                "Field_Type"=>getTypeName($FieldInfo->{"Type"}, 1));
    1318715                        }
    1319716                    }
     
    1323720        else
    1324721        { # removed
    1325             if(defined $Class1{"Annotation"})
     722            if(defined $Class1->{"Annotation"})
    1326723            {
    1327724                %{$CompatProblems{".client_method"}{"Removed_Annotation"}{"this"}} = (
    1328725                    "Type_Name"=>$ClassName,
    1329                     "Target"=>$ClassName  );
     726                    "Target"=>$ClassName);
    1330727            }
    1331728           
     
    1335732                if(not defined $ReportedRemoved{$ClassName})
    1336733                {
    1337                     foreach my $Field (keys(%{$Class1{"Fields"}}))
     734                    foreach my $Field (keys(%{$Class1->{"Fields"}}))
    1338735                    {
    1339                         my $FieldInfo = $Class1{"Fields"}{$Field};
     736                        my $FieldInfo = $Class1->{"Fields"}{$Field};
    1340737                       
    1341738                        my $FAccess = $FieldInfo->{"Access"};
     
    1348745                            $CheckedTypes{$ClassName} = 1;
    1349746                           
    1350                             if($Class1{"Type"} eq "class")
     747                            if($Class1->{"Type"} eq "class")
    1351748                            {
    1352749                                %{$CompatProblems{".client_method"}{"Removed_Class"}{"this"}} = (
    1353750                                    "Type_Name"=>$ClassName,
    1354                                     "Target"=>$ClassName  );
     751                                    "Target"=>$ClassName);
    1355752                            }
    1356753                            else
     
    1358755                                %{$CompatProblems{".client_method"}{"Removed_Interface"}{"this"}} = (
    1359756                                    "Type_Name"=>$ClassName,
    1360                                     "Target"=>$ClassName  );
     757                                    "Target"=>$ClassName);
    1361758                            }
    1362759                        }
     
    1405802sub pushType($$)
    1406803{
    1407     my %TypeDescriptor=(
     804    my %TypeDescriptor = (
    1408805        "Tid1"  => $_[0],
    1409         "Tid2"  => $_[1]  );
     806        "Tid2"  => $_[1]);
    1410807    push(@RecurTypes, \%TypeDescriptor);
    1411808}
    1412809
    1413 sub get_SFormat($)
     810sub getSFormat($)
    1414811{
    1415812    my $Name = $_[0];
     
    1418815}
    1419816
    1420 sub get_PFormat($)
    1421 {
    1422     my $Name = $_[0];
    1423     $Name=~s/\//./g;
    1424     return $Name;
    1425 }
    1426 
    1427 sub get_ConstantValue($$)
     817sub getConstantValue($$)
    1428818{
    1429819    my ($Value, $ValueType) = @_;
    1430     return "" if(not $Value);
     820   
     821    if(not defined $Value) {
     822        return undef;
     823    }
     824   
    1431825    if($Value eq "\@EMPTY_STRING\@") {
    1432826        return "\"\"";
     
    1435829        return "\"".$Value."\"";
    1436830    }
    1437     else {
    1438         return $Value;
    1439     }
     831   
     832    return $Value;
    1440833}
    1441834
     
    1466859    }
    1467860   
    1468     my %Type1 = get_Type($Type1_Id, 1);
    1469     my %Type2 = get_Type($Type2_Id, 2);
    1470861    if(isRecurType($Type1_Id, $Type2_Id))
    1471862    { # do not follow to recursive declarations
    1472863        return {};
    1473864    }
     865   
     866    my %Type1 = %{getType($Type1_Id, 1)};
     867    my %Type2 = %{getType($Type2_Id, 2)};
     868   
    1474869    return {} if(not $Type1{"Name"} or not $Type2{"Name"});
    1475870    return {} if(not $Type1{"Archive"} or not $Type2{"Archive"});
     
    1502897    {
    1503898        %{$SubProblems{"Class_Became_Interface"}{""}}=(
    1504             "Type_Name"=>$Type1{"Name"}  );
     899            "Type_Name"=>$Type1{"Name"});
    1505900       
    1506901        return ($Cache{"mergeTypes"}{$Type1_Id}{$Type2_Id} = \%SubProblems);
     
    1510905    {
    1511906        %{$SubProblems{"Interface_Became_Class"}{""}}=(
    1512             "Type_Name"=>$Type1{"Name"}  );
     907            "Type_Name"=>$Type1{"Name"});
    1513908       
    1514909        return ($Cache{"mergeTypes"}{$Type1_Id}{$Type2_Id} = \%SubProblems);
     
    1519914        %{$SubProblems{"Class_Became_Final"}{""}}=(
    1520915            "Type_Name"=>$Type1{"Name"},
    1521             "Target"=>$Type1{"Name"}  );
     916            "Target"=>$Type1{"Name"});
    1522917    }
    1523918    if(not $Type1{"Abstract"}
     
    1525920    {
    1526921        %{$SubProblems{"Class_Became_Abstract"}{""}}=(
    1527             "Type_Name"=>$Type1{"Name"}  );
     922            "Type_Name"=>$Type1{"Name"});
    1528923    }
    1529924   
     
    1538933                if(my @InvokedBy = sort keys(%{$MethodUsed{2}{$AddedMethod}}))
    1539934                {
    1540                     %{$SubProblems{"Abstract_Class_Added_Abstract_Method_Invoked_By_Others"}{get_SFormat($AddedMethod)}} = (
     935                    %{$SubProblems{"Abstract_Class_Added_Abstract_Method_Invoked_By_Others"}{getSFormat($AddedMethod)}} = (
    1541936                        "Type_Name"=>$Type1{"Name"},
    1542937                        "Type_Type"=>$Type1{"Type"},
    1543938                        "Target"=>$AddedMethod,
    1544                         "InvokedBy"=>$InvokedBy[0]  );
     939                        "Invoked_By"=>$InvokedBy[0]);
    1545940                }
    1546941                else
    1547942                {
    1548                     %{$SubProblems{"Abstract_Class_Added_Abstract_Method"}{get_SFormat($AddedMethod)}} = (
     943                    %{$SubProblems{"Abstract_Class_Added_Abstract_Method"}{getSFormat($AddedMethod)}} = (
    1549944                        "Type_Name"=>$Type1{"Name"},
    1550945                        "Type_Type"=>$Type1{"Type"},
    1551                         "Target"=>$AddedMethod  );
     946                        "Target"=>$AddedMethod);
    1552947                }
    1553948            }
    1554949            else
    1555950            {
    1556                 %{$SubProblems{"NonAbstract_Class_Added_Abstract_Method"}{get_SFormat($AddedMethod)}} = (
     951                %{$SubProblems{"NonAbstract_Class_Added_Abstract_Method"}{getSFormat($AddedMethod)}} = (
    1557952                    "Type_Name"=>$Type1{"Name"},
    1558953                    "Type_Type"=>$Type1{"Type"},
    1559                     "Target"=>$AddedMethod  );
     954                    "Target"=>$AddedMethod);
    1560955            }
    1561956        }
     
    1564959            if(my @InvokedBy = sort keys(%{$MethodUsed{2}{$AddedMethod}}))
    1565960            {
    1566                 %{$SubProblems{"Interface_Added_Abstract_Method_Invoked_By_Others"}{get_SFormat($AddedMethod)}} = (
     961                %{$SubProblems{"Interface_Added_Abstract_Method_Invoked_By_Others"}{getSFormat($AddedMethod)}} = (
    1567962                    "Type_Name"=>$Type1{"Name"},
    1568963                    "Type_Type"=>$Type1{"Type"},
    1569964                    "Target"=>$AddedMethod,
    1570                     "InvokedBy"=>$InvokedBy[0]  );
     965                    "Invoked_By"=>$InvokedBy[0]);
    1571966            }
    1572967            else
    1573968            {
    1574                 %{$SubProblems{"Interface_Added_Abstract_Method"}{get_SFormat($AddedMethod)}} = (
     969                %{$SubProblems{"Interface_Added_Abstract_Method"}{getSFormat($AddedMethod)}} = (
    1575970                    "Type_Name"=>$Type1{"Name"},
    1576971                    "Type_Type"=>$Type1{"Type"},
    1577                     "Target"=>$AddedMethod  );
     972                    "Target"=>$AddedMethod);
    1578973            }
    1579974        }
     
    1583978        if($Type1{"Type"} eq "class")
    1584979        {
    1585             %{$SubProblems{"Class_Removed_Abstract_Method"}{get_SFormat($RemovedMethod)}} = (
     980            %{$SubProblems{"Class_Removed_Abstract_Method"}{getSFormat($RemovedMethod)}} = (
    1586981                "Type_Name"=>$Type1{"Name"},
    1587982                "Type_Type"=>$Type1{"Type"},
    1588                 "Target"=>$RemovedMethod  );
     983                "Target"=>$RemovedMethod);
    1589984        }
    1590985        else
    1591986        {
    1592             %{$SubProblems{"Interface_Removed_Abstract_Method"}{get_SFormat($RemovedMethod)}} = (
     987            %{$SubProblems{"Interface_Removed_Abstract_Method"}{getSFormat($RemovedMethod)}} = (
    1593988                "Type_Name"=>$Type1{"Name"},
    1594989                "Type_Type"=>$Type1{"Type"},
    1595                 "Target"=>$RemovedMethod  );
     990                "Target"=>$RemovedMethod);
    1596991        }
    1597992    }
     
    1599994    and $Type2{"Type"} eq "class")
    1600995    {
    1601         my %SuperClass1 = get_Type($Type1{"SuperClass"}, 1);
    1602         my %SuperClass2 = get_Type($Type2{"SuperClass"}, 2);
    1603         if($SuperClass2{"Name"} ne $SuperClass1{"Name"})
    1604         {
    1605             if($SuperClass1{"Name"} eq "java.lang.Object"
    1606             or not $SuperClass1{"Name"})
     996        my $SuperClass1 = getType($Type1{"SuperClass"}, 1);
     997        my $SuperClass2 = getType($Type2{"SuperClass"}, 2);
     998       
     999        my $SuperClassName1 = $SuperClass1->{"Name"};
     1000        my $SuperClassName2 = $SuperClass2->{"Name"};
     1001       
     1002        if($SuperClassName2 ne $SuperClassName1)
     1003        {
     1004            if($SuperClassName1 eq "java.lang.Object"
     1005            or not $SuperClassName1)
    16071006            {
    16081007              # Java 6: java.lang.Object
    16091008              # Java 7: none
    1610                 if($SuperClass2{"Name"} ne "java.lang.Object")
     1009                if($SuperClassName2 ne "java.lang.Object")
    16111010                {
    1612                     if($SuperClass2{"Abstract"}
     1011                    if($SuperClass2->{"Abstract"}
    16131012                    and $Type1{"Abstract"} and $Type2{"Abstract"}
    1614                     and keys(%{$Class_AbstractMethods{2}{$SuperClass2{"Name"}}}))
     1013                    and keys(%{$Class_AbstractMethods{2}{$SuperClassName2}}))
    16151014                    {
    16161015                        if(my ($Invoked, $InvokedBy) = getInvoked($Type1{"Name"}))
     
    16181017                            %{$SubProblems{"Abstract_Class_Added_Super_Abstract_Class_Invoked_By_Others"}{""}} = (
    16191018                                "Type_Name"=>$Type1{"Name"},
    1620                                 "Target"=>$SuperClass2{"Name"},
     1019                                "Target"=>$SuperClassName2,
    16211020                                "Invoked"=>$Invoked,
    1622                                 "InvokedBy"=>$InvokedBy  );
     1021                                "Invoked_By"=>$InvokedBy);
    16231022                        }
    16241023                        else
     
    16261025                            %{$SubProblems{"Abstract_Class_Added_Super_Abstract_Class"}{""}} = (
    16271026                                "Type_Name"=>$Type1{"Name"},
    1628                                 "Target"=>$SuperClass2{"Name"}  );
     1027                                "Target"=>$SuperClassName2);
    16291028                        }
    16301029                    }
     
    16331032                        %{$SubProblems{"Added_Super_Class"}{""}} = (
    16341033                            "Type_Name"=>$Type1{"Name"},
    1635                             "Target"=>$SuperClass2{"Name"}  );
    1636                     }
    1637                 }
    1638             }
    1639             elsif($SuperClass2{"Name"} eq "java.lang.Object"
    1640             or not $SuperClass2{"Name"})
     1034                            "Target"=>$SuperClassName2);
     1035                    }
     1036                }
     1037            }
     1038            elsif($SuperClassName2 eq "java.lang.Object"
     1039            or not $SuperClassName2)
    16411040            {
    16421041              # Java 6: java.lang.Object
    16431042              # Java 7: none
    1644                 if($SuperClass1{"Name"} ne "java.lang.Object")
     1043                if($SuperClassName1 ne "java.lang.Object")
    16451044                {
    16461045                    %{$SubProblems{"Removed_Super_Class"}{""}} = (
    16471046                        "Type_Name"=>$Type1{"Name"},
    1648                         "Target"=>$SuperClass1{"Name"}  );
     1047                        "Target"=>$SuperClassName1);
    16491048                }
    16501049            }
     
    16531052                %{$SubProblems{"Changed_Super_Class"}{""}} = (
    16541053                    "Type_Name"=>$Type1{"Name"},
    1655                     "Target"=>$SuperClass1{"Name"},
    1656                     "Old_Value"=>$SuperClass1{"Name"},
    1657                     "New_Value"=>$SuperClass2{"Name"}  );
    1658             }
    1659         }
    1660     }
    1661     my %SuperInterfaces_Old = map {get_TypeName($_, 1) => 1} keys(%{$Type1{"SuperInterface"}});
    1662     my %SuperInterfaces_New = map {get_TypeName($_, 2) => 1} keys(%{$Type2{"SuperInterface"}});
     1054                    "Target"=>$SuperClassName1,
     1055                    "Old_Value"=>$SuperClassName1,
     1056                    "New_Value"=>$SuperClassName2);
     1057            }
     1058        }
     1059    }
     1060    my %SuperInterfaces_Old = map {getTypeName($_, 1) => 1} keys(%{$Type1{"SuperInterface"}});
     1061    my %SuperInterfaces_New = map {getTypeName($_, 2) => 1} keys(%{$Type2{"SuperInterface"}});
    16631062    foreach my $SuperInterface (keys(%SuperInterfaces_New))
    16641063    {
     
    16751074                    if($HaveMethods and checkDefaultImpl(2, $SuperInterface, $Type2{"Name"}))
    16761075                    {
    1677                         %{$SubProblems{"Interface_Added_Super_Interface_With_Implemented_Methods"}{get_SFormat($SuperInterface)}} = (
     1076                        %{$SubProblems{"Interface_Added_Super_Interface_With_Implemented_Methods"}{getSFormat($SuperInterface)}} = (
    16781077                            "Type_Name"=>$Type1{"Name"},
    1679                             "Target"=>$SuperInterface  );
     1078                            "Target"=>$SuperInterface);
    16801079                    }
    16811080                    else
     
    16831082                        if(my ($Invoked, $InvokedBy) = getInvoked($Type1{"Name"}))
    16841083                        {
    1685                             %{$SubProblems{"Interface_Added_Super_Interface_Used_By_Others"}{get_SFormat($SuperInterface)}} = (
     1084                            %{$SubProblems{"Interface_Added_Super_Interface_Used_By_Others"}{getSFormat($SuperInterface)}} = (
    16861085                                "Type_Name"=>$Type1{"Name"},
    16871086                                "Target"=>$SuperInterface,
    16881087                                "Invoked"=>$Invoked,
    1689                                 "InvokedBy"=>$InvokedBy  );
     1088                                "Invoked_By"=>$InvokedBy);
    16901089                        }
    16911090                        else
    16921091                        {
    1693                             %{$SubProblems{"Interface_Added_Super_Interface"}{get_SFormat($SuperInterface)}} = (
     1092                            %{$SubProblems{"Interface_Added_Super_Interface"}{getSFormat($SuperInterface)}} = (
    16941093                                "Type_Name"=>$Type1{"Name"},
    1695                                 "Target"=>$SuperInterface  );
     1094                                "Target"=>$SuperInterface);
    16961095                        }
    16971096                    }
     
    16991098                elsif($HaveFields)
    17001099                {
    1701                     %{$SubProblems{"Interface_Added_Super_Constant_Interface"}{get_SFormat($SuperInterface)}} = (
     1100                    %{$SubProblems{"Interface_Added_Super_Constant_Interface"}{getSFormat($SuperInterface)}} = (
    17021101                        "Type_Name"=>$Type2{"Name"},
    1703                         "Target"=>$SuperInterface  );
     1102                        "Target"=>$SuperInterface);
    17041103                }
    17051104                else
     
    17141113                    if($HaveMethods and checkDefaultImpl(2, $SuperInterface, $Type2{"Name"}))
    17151114                    {
    1716                         %{$SubProblems{"Abstract_Class_Added_Super_Interface_With_Implemented_Methods"}{get_SFormat($SuperInterface)}} = (
     1115                        %{$SubProblems{"Abstract_Class_Added_Super_Interface_With_Implemented_Methods"}{getSFormat($SuperInterface)}} = (
    17171116                            "Type_Name"=>$Type1{"Name"},
    1718                             "Target"=>$SuperInterface  );
     1117                            "Target"=>$SuperInterface);
    17191118                    }
    17201119                    else
     
    17221121                        if(my ($Invoked, $InvokedBy) = getInvoked($Type1{"Name"}))
    17231122                        {
    1724                             %{$SubProblems{"Abstract_Class_Added_Super_Interface_Invoked_By_Others"}{get_SFormat($SuperInterface)}} = (
     1123                            %{$SubProblems{"Abstract_Class_Added_Super_Interface_Invoked_By_Others"}{getSFormat($SuperInterface)}} = (
    17251124                                "Type_Name"=>$Type1{"Name"},
    17261125                                "Target"=>$SuperInterface,
    17271126                                "Invoked"=>$Invoked,
    1728                                 "InvokedBy"=>$InvokedBy  );
     1127                                "Invoked_By"=>$InvokedBy);
    17291128                        }
    17301129                        else
    17311130                        {
    1732                             %{$SubProblems{"Abstract_Class_Added_Super_Interface"}{get_SFormat($SuperInterface)}} = (
     1131                            %{$SubProblems{"Abstract_Class_Added_Super_Interface"}{getSFormat($SuperInterface)}} = (
    17331132                                "Type_Name"=>$Type1{"Name"},
    1734                                 "Target"=>$SuperInterface  );
     1133                                "Target"=>$SuperInterface);
    17351134                        }
    17361135                    }
     
    17511150                or $SuperInterface=~/\Ajava\./)
    17521151                {
    1753                     %{$SubProblems{"Interface_Removed_Super_Interface"}{get_SFormat($SuperInterface)}} = (
     1152                    %{$SubProblems{"Interface_Removed_Super_Interface"}{getSFormat($SuperInterface)}} = (
    17541153                        "Type_Name"=>$Type1{"Name"},
    17551154                        "Type_Type"=>"interface",
    1756                         "Target"=>$SuperInterface  );
     1155                        "Target"=>$SuperInterface);
    17571156                }
    17581157                elsif($HaveFields)
    17591158                {
    1760                     %{$SubProblems{"Interface_Removed_Super_Constant_Interface"}{get_SFormat($SuperInterface)}} = (
     1159                    %{$SubProblems{"Interface_Removed_Super_Constant_Interface"}{getSFormat($SuperInterface)}} = (
    17611160                        "Type_Name"=>$Type1{"Name"},
    1762                         "Target"=>$SuperInterface  );
     1161                        "Target"=>$SuperInterface);
    17631162                }
    17641163                else {
     
    17681167            else
    17691168            {
    1770                 %{$SubProblems{"Class_Removed_Super_Interface"}{get_SFormat($SuperInterface)}} = (
     1169                %{$SubProblems{"Class_Removed_Super_Interface"}{getSFormat($SuperInterface)}} = (
    17711170                    "Type_Name"=>$Type1{"Name"},
    17721171                    "Type_Type"=>"class",
    1773                     "Target"=>$SuperInterface  );
     1172                    "Target"=>$SuperInterface);
    17741173            }
    17751174        }
     
    17851184        my $Field_Pos1 = $Type1{"Fields"}{$Field_Name}{"Pos"};
    17861185        my $FieldType1_Id = $Type1{"Fields"}{$Field_Name}{"Type"};
    1787         my %FieldType1 = get_Type($FieldType1_Id, 1);
     1186        my $FieldType1_Name = getTypeName($FieldType1_Id, 1);
    17881187       
    17891188        if(not $Type2{"Fields"}{$Field_Name})
     
    17911190            my $StraightPair_Name = findFieldPair($Field_Pos1, \%Type2);
    17921191            if($StraightPair_Name ne "lost" and not $Type1{"Fields"}{$StraightPair_Name}
    1793             and $FieldType1{"Name"} eq get_TypeName($Type2{"Fields"}{$StraightPair_Name}{"Type"}, 2))
    1794             {
    1795                 if(my $Constant = get_ConstantValue($Type1{"Fields"}{$Field_Name}{"Value"}, $FieldType1{"Name"}))
     1192            and $FieldType1_Name eq getTypeName($Type2{"Fields"}{$StraightPair_Name}{"Type"}, 2))
     1193            {
     1194                if(my $Constant = getConstantValue($Type1{"Fields"}{$Field_Name}{"Value"}, $FieldType1_Name))
    17961195                {
    17971196                    %{$SubProblems{"Renamed_Constant_Field"}{$Field_Name}}=(
     
    18001199                        "Old_Value"=>$Field_Name,
    18011200                        "New_Value"=>$StraightPair_Name,
    1802                         "Field_Type"=>$FieldType1{"Name"},
    1803                         "Field_Value"=>$Constant  );
     1201                        "Field_Type"=>$FieldType1_Name,
     1202                        "Field_Value"=>$Constant);
    18041203                }
    18051204                else
     
    18101209                        "Old_Value"=>$Field_Name,
    18111210                        "New_Value"=>$StraightPair_Name,
    1812                         "Field_Type"=>$FieldType1{"Name"}  );
     1211                        "Field_Type"=>$FieldType1_Name);
    18131212                }
    18141213            }
    18151214            else
    18161215            {
    1817                 if(my $Constant = get_ConstantValue($Type1{"Fields"}{$Field_Name}{"Value"}, $FieldType1{"Name"}))
     1216                if(my $Constant = getConstantValue($Type1{"Fields"}{$Field_Name}{"Value"}, $FieldType1_Name))
    18181217                { # has a compile-time constant value
    18191218                    %{$SubProblems{"Removed_Constant_Field"}{$Field_Name}}=(
     
    18211220                        "Type_Name"=>$Type1{"Name"},
    18221221                        "Field_Value"=>$Constant,
    1823                         "Field_Type"=>$FieldType1{"Name"},
    1824                         "Type_Type"=>$Type1{"Type"}  );
     1222                        "Field_Type"=>$FieldType1_Name,
     1223                        "Type_Type"=>$Type1{"Type"});
    18251224                }
    18261225                else
     
    18301229                        "Type_Name"=>$Type1{"Name"},
    18311230                        "Type_Type"=>$Type1{"Type"},
    1832                         "Field_Type"=>$FieldType1{"Name"}  );
     1231                        "Field_Type"=>$FieldType1_Name);
    18331232                }
    18341233            }
    18351234            next;
    18361235        }
     1236       
    18371237        my $FieldType2_Id = $Type2{"Fields"}{$Field_Name}{"Type"};
    1838         my %FieldType2 = get_Type($FieldType2_Id, 2);
     1238        my $FieldType2_Name = getTypeName($FieldType2_Id, 2);
    18391239       
    18401240        if(not $Type1{"Fields"}{$Field_Name}{"Static"}
     
    18451245                %{$SubProblems{"NonConstant_Field_Became_Static"}{$Field_Name}}=(
    18461246                    "Target"=>$Field_Name,
    1847                     "Field_Type"=>$FieldType1{"Name"},
    1848                     "Type_Name"=>$Type1{"Name"}  );
     1247                    "Field_Type"=>$FieldType1_Name,
     1248                    "Type_Name"=>$Type1{"Name"});
    18491249            }
    18501250        }
     
    18561256                %{$SubProblems{"Constant_Field_Became_NonStatic"}{$Field_Name}}=(
    18571257                    "Target"=>$Field_Name,
    1858                     "Field_Type"=>$FieldType1{"Name"},
    1859                     "Type_Name"=>$Type1{"Name"}  );
     1258                    "Field_Type"=>$FieldType1_Name,
     1259                    "Type_Name"=>$Type1{"Name"});
    18601260            }
    18611261            else
     
    18631263                %{$SubProblems{"NonConstant_Field_Became_NonStatic"}{$Field_Name}}=(
    18641264                    "Target"=>$Field_Name,
    1865                     "Field_Type"=>$FieldType1{"Name"},
    1866                     "Type_Name"=>$Type1{"Name"}  );
     1265                    "Field_Type"=>$FieldType1_Name,
     1266                    "Type_Name"=>$Type1{"Name"});
    18671267            }
    18681268        }
     
    18721272            %{$SubProblems{"Field_Became_Final"}{$Field_Name}}=(
    18731273                "Target"=>$Field_Name,
    1874                 "Field_Type"=>$FieldType1{"Name"},
    1875                 "Type_Name"=>$Type1{"Name"}  );
     1274                "Field_Type"=>$FieldType1_Name,
     1275                "Type_Name"=>$Type1{"Name"});
    18761276        }
    18771277        elsif($Type1{"Fields"}{$Field_Name}{"Final"}
     
    18801280            %{$SubProblems{"Field_Became_NonFinal"}{$Field_Name}}=(
    18811281                "Target"=>$Field_Name,
    1882                 "Field_Type"=>$FieldType1{"Name"},
    1883                 "Type_Name"=>$Type1{"Name"}  );
     1282                "Field_Type"=>$FieldType1_Name,
     1283                "Type_Name"=>$Type1{"Name"});
    18841284        }
    18851285        my $Access2 = $Type2{"Fields"}{$Field_Name}{"Access"};
     
    18871287        or $Access1 eq "protected" and $Access2=~/private/)
    18881288        {
    1889             %{$SubProblems{"Changed_Field_Access"}{$Field_Name}}=(
    1890                 "Target"=>$Field_Name,
    1891                 "Type_Name"=>$Type1{"Name"},
    1892                 "Old_Value"=>$Access1,
    1893                 "New_Value"=>$Access2  );
    1894         }
    1895        
    1896         my $Value1 = get_ConstantValue($Type1{"Fields"}{$Field_Name}{"Value"}, $FieldType1{"Name"});
    1897         my $Value2 = get_ConstantValue($Type2{"Fields"}{$Field_Name}{"Value"}, $FieldType2{"Name"});
     1289            if($Access2 eq "package-private")
     1290            {
     1291                %{$SubProblems{"Changed_Field_Access_To_Package_Private"}{$Field_Name}}=(
     1292                    "Target"=>$Field_Name,
     1293                    "Type_Name"=>$Type1{"Name"},
     1294                    "Old_Value"=>$Access1,
     1295                    "New_Value"=>$Access2);
     1296            }
     1297            else
     1298            {
     1299                %{$SubProblems{"Changed_Field_Access"}{$Field_Name}}=(
     1300                    "Target"=>$Field_Name,
     1301                    "Type_Name"=>$Type1{"Name"},
     1302                    "Old_Value"=>$Access1,
     1303                    "New_Value"=>$Access2);
     1304            }
     1305        }
     1306       
     1307        my $Value1 = getConstantValue($Type1{"Fields"}{$Field_Name}{"Value"}, $FieldType1_Name);
     1308        my $Value2 = getConstantValue($Type2{"Fields"}{$Field_Name}{"Value"}, $FieldType2_Name);
    18981309       
    18991310        if($Value1 ne $Value2)
     
    19081319                        %{$SubProblems{"Changed_Final_Version_Field_Value"}{$Field_Name}}=(
    19091320                            "Target"=>$Field_Name,
    1910                             "Field_Type"=>$FieldType1{"Name"},
     1321                            "Field_Type"=>$FieldType1_Name,
    19111322                            "Type_Name"=>$Type1{"Name"},
    19121323                            "Old_Value"=>$Value1,
    1913                             "New_Value"=>$Value2  );
     1324                            "New_Value"=>$Value2);
    19141325                    }
    19151326                    else
     
    19171328                        %{$SubProblems{"Changed_Final_Field_Value"}{$Field_Name}}=(
    19181329                            "Target"=>$Field_Name,
    1919                             "Field_Type"=>$FieldType1{"Name"},
     1330                            "Field_Type"=>$FieldType1_Name,
    19201331                            "Type_Name"=>$Type1{"Name"},
    19211332                            "Old_Value"=>$Value1,
    1922                             "New_Value"=>$Value2  );
     1333                            "New_Value"=>$Value2);
    19231334                    }
    19241335                }
     
    19481359                foreach my $Sub_SubLocation (sort {length($a)<=>length($b)} sort keys(%{$Sub_SubProblems->{$Sub_SubProblemType}}))
    19491360                {
    1950                     if(not defined $AllAffected)
     1361                    if(not defined $In::Opt{"AllAffected"})
    19511362                    {
    19521363                        if(defined $DupProblems{$Sub_SubProblems->{$Sub_SubProblemType}{$Sub_SubLocation}}) {
     
    19581369                    $SubProblems{$Sub_SubProblemType}{$NewLocation} = $Sub_SubProblems->{$Sub_SubProblemType}{$Sub_SubLocation};
    19591370                   
    1960                     if(not defined $AllAffected)
     1371                    if(not defined $In::Opt{"AllAffected"})
    19611372                    {
    19621373                        $DupProblems{$Sub_SubProblems->{$Sub_SubProblemType}{$Sub_SubLocation}} = 1;
     
    19751386        my $FieldPos2 = $Type2{"Fields"}{$Field_Name}{"Pos"};
    19761387        my $FieldType2_Id = $Type2{"Fields"}{$Field_Name}{"Type"};
    1977         my %FieldType2 = get_Type($FieldType2_Id, 2);
     1388        my $FieldType2_Name = getTypeName($FieldType2_Id, 2);
    19781389       
    19791390        if(not $Type1{"Fields"}{$Field_Name})
     
    19811392            my $StraightPair_Name = findFieldPair($FieldPos2, \%Type1);
    19821393            if($StraightPair_Name ne "lost" and not $Type2{"Fields"}{$StraightPair_Name}
    1983             and get_TypeName($Type1{"Fields"}{$StraightPair_Name}{"Type"}, 1) eq $FieldType2{"Name"})
     1394            and getTypeName($Type1{"Fields"}{$StraightPair_Name}{"Type"}, 1) eq $FieldType2_Name)
    19841395            {
    19851396                # Already reported as "Renamed_Field" or "Renamed_Constant_Field"
     
    19911402                    %{$SubProblems{"Interface_Added_Field"}{$Field_Name}}=(
    19921403                        "Target"=>$Field_Name,
    1993                         "Type_Name"=>$Type1{"Name"}  );
     1404                        "Type_Name"=>$Type1{"Name"});
    19941405                }
    19951406                else
     
    19971408                    %{$SubProblems{"Class_Added_Field"}{$Field_Name}}=(
    19981409                        "Target"=>$Field_Name,
    1999                         "Type_Name"=>$Type1{"Name"}  );
     1410                        "Type_Name"=>$Type1{"Name"});
    20001411                }
    20011412            }
     
    20101421{ # Check if all abstract methods of the super class have
    20111422  # default implementations in the class
    2012     my ($LibVersion, $SuperClassName, $ClassName) = @_;
    2013    
    2014     foreach my $Method (keys(%{$Class_AbstractMethods{$LibVersion}{$SuperClassName}}))
    2015     {
    2016         if(my $Overridden = findMethod_Class($Method, $ClassName, $LibVersion))
    2017         {
    2018             if($MethodInfo{$LibVersion}{$Overridden}{"Abstract"}) {
     1423    my ($LVer, $SuperClassName, $ClassName) = @_;
     1424   
     1425    foreach my $Method (keys(%{$Class_AbstractMethods{$LVer}{$SuperClassName}}))
     1426    {
     1427        if(my $Overridden = findMethod_Class($Method, $ClassName, $LVer))
     1428        {
     1429            if($MethodInfo{$LVer}{$Overridden}{"Abstract"}) {
    20191430                return 0;
    20201431            }
     
    20281439}
    20291440
    2030 sub unmangle($)
    2031 {
    2032     my $Name = $_[0];
    2033     $Name=~s!/!.!g;
    2034     $Name=~s!:\(!(!g;
    2035     $Name=~s!\).+\Z!)!g;
    2036     if($Name=~/\A(.+)\((.+)\)/)
    2037     {
    2038         my ($ShortName, $MangledParams) = ($1, $2);
    2039         my @UnmangledParams = ();
    2040         my ($IsArray, $Shift, $Pos, $CurParam) = (0, 0, 0, "");
    2041         while($Pos<length($MangledParams))
    2042         {
    2043             my $Symbol = substr($MangledParams, $Pos, 1);
    2044             if($Symbol eq "[")
    2045             { # array
    2046                 $IsArray = 1;
    2047                 $Pos+=1;
    2048             }
    2049             elsif($Symbol eq "L")
    2050             { # class
    2051                 if(substr($MangledParams, $Pos+1)=~/\A(.+?);/) {
    2052                     $CurParam = $1;
    2053                     $Shift = length($CurParam)+2;
    2054                 }
    2055                 if($IsArray) {
    2056                     $CurParam .= "[]";
    2057                 }
    2058                 $Pos+=$Shift;
    2059                 push(@UnmangledParams, $CurParam);
    2060                 ($IsArray, $Shift, $CurParam) = (0, 0, "")
    2061             }
    2062             else
    2063             {
    2064                 if($Symbol eq "C") {
    2065                     $CurParam = "char";
    2066                 }
    2067                 elsif($Symbol eq "B") {
    2068                     $CurParam = "byte";
    2069                 }
    2070                 elsif($Symbol eq "S") {
    2071                     $CurParam = "short";
    2072                 }
    2073                 elsif($Symbol eq "S") {
    2074                     $CurParam = "short";
    2075                 }
    2076                 elsif($Symbol eq "I") {
    2077                     $CurParam = "int";
    2078                 }
    2079                 elsif($Symbol eq "F") {
    2080                     $CurParam = "float";
    2081                 }
    2082                 elsif($Symbol eq "J") {
    2083                     $CurParam = "long";
    2084                 }
    2085                 elsif($Symbol eq "D") {
    2086                     $CurParam = "double";
    2087                 }
    2088                 else {
    2089                     printMsg("INFO", "WARNING: unmangling error");
    2090                 }
    2091                 if($IsArray) {
    2092                     $CurParam .= "[]";
    2093                 }
    2094                 $Pos+=1;
    2095                 push(@UnmangledParams, $CurParam);
    2096                 ($IsArray, $Shift, $CurParam) = (0, 0, "")
    2097             }
    2098         }
    2099         return $ShortName."(".join(", ", @UnmangledParams).")";
    2100     }
    2101     else {
    2102         return $Name;
    2103     }
    2104 }
    2105 
    2106 sub get_TypeName($$)
    2107 {
    2108     my ($TypeId, $LibVersion) = @_;
    2109     return $TypeInfo{$LibVersion}{$TypeId}{"Name"};
    2110 }
    2111 
    2112 sub get_ShortName($$)
    2113 {
    2114     my ($TypeId, $LibVersion) = @_;
    2115     my $TypeName = $TypeInfo{$LibVersion}{$TypeId}{"Name"};
    2116     $TypeName=~s/\A.*\.//g;
    2117     return $TypeName;
    2118 }
    2119 
    2120 sub get_TypeType($$)
    2121 {
    2122     my ($TypeId, $LibVersion) = @_;
    2123     return $TypeInfo{$LibVersion}{$TypeId}{"Type"};
    2124 }
    2125 
    2126 sub get_TypeHeader($$)
    2127 {
    2128     my ($TypeId, $LibVersion) = @_;
    2129     return $TypeInfo{$LibVersion}{$TypeId}{"Header"};
    2130 }
    2131 
    2132 sub get_BaseType($$)
    2133 {
    2134     my ($TypeId, $LibVersion) = @_;
    2135     return "" if(not $TypeId);
    2136     if(defined $Cache{"get_BaseType"}{$TypeId}{$LibVersion}) {
    2137         return %{$Cache{"get_BaseType"}{$TypeId}{$LibVersion}};
    2138     }
    2139     return "" if(not $TypeInfo{$LibVersion}{$TypeId});
    2140     my %Type = %{$TypeInfo{$LibVersion}{$TypeId}};
    2141     return %Type if(not $Type{"BaseType"});
    2142     %Type = get_BaseType($Type{"BaseType"}, $LibVersion);
    2143     $Cache{"get_BaseType"}{$TypeId}{$LibVersion} = \%Type;
    2144     return %Type;
    2145 }
    2146 
    2147 sub get_OneStep_BaseType($$)
    2148 {
    2149     my ($TypeId, $LibVersion) = @_;
    2150     return "" if(not $TypeId);
    2151     return "" if(not $TypeInfo{$LibVersion}{$TypeId});
    2152     my %Type = %{$TypeInfo{$LibVersion}{$TypeId}};
    2153     return %Type if(not $Type{"BaseType"});
    2154     return get_Type($Type{"BaseType"}, $LibVersion);
    2155 }
    2156 
    2157 sub get_Type($$)
    2158 {
    2159     my ($TypeId, $LibVersion) = @_;
    2160     return "" if(not $TypeId);
    2161     return "" if(not $TypeInfo{$LibVersion}{$TypeId});
    2162     return %{$TypeInfo{$LibVersion}{$TypeId}};
    2163 }
    2164 
    2165 sub classFilter($$$)
    2166 {
    2167     my ($Class, $LibVersion, $ClassContext) = @_;
    2168    
    2169     if(defined $Class->{"Dep"}) {
    2170         return 0;
    2171     }
    2172    
    2173     my $CName = $Class->{"Name"};
    2174     my $Package = $Class->{"Package"};
    2175    
    2176     if(defined $ClassListPath
    2177     and not defined $ClassList_User{$CName})
    2178     { # user defined classes
    2179         return 0;
    2180     }
    2181    
    2182     if(defined $SkipClassesList
    2183     and defined $SkipClasses{$CName})
    2184     { # user defined classes
    2185         return 0;
    2186     }
    2187    
    2188     if(skipPackage($Package, $LibVersion))
    2189     { # internal packages
    2190         return 0;
    2191     }
    2192    
    2193     if(skipType($CName))
    2194     { # internal types
    2195         return 0;
    2196     }
    2197    
    2198     if($ClassContext)
    2199     {
    2200         my @Ann = ();
    2201        
    2202         if(defined $Class->{"Annotations"}) {
    2203             @Ann = keys(%{$Class->{"Annotations"}});
    2204         }
    2205        
    2206         if(not annotationFilter(\@Ann, $LibVersion)) {
    2207             return 0;
    2208         }
    2209        
    2210         if($ClientPath)
    2211         {
    2212             if(not defined $UsedClasses_Client{$CName}) {
    2213                 return 0;
    2214             }
    2215         }
    2216     }
    2217    
    2218     return 1;
    2219 }
    2220 
    2221 sub annotationFilter($$)
    2222 {
    2223     my ($Ann, $LibVersion) = @_;
    2224    
    2225     if(not defined $CountMethods)
    2226     {
    2227         if(defined $AddedAnnotations and $LibVersion==1) {
    2228             return 1;
    2229         }
    2230        
    2231         if(defined $RemovedAnnotations and $LibVersion==2) {
    2232             return 1;
    2233         }
    2234     }
    2235    
    2236     if($SkipAnnotationsListPath)
    2237     {
    2238         foreach my $Aid (@{$Ann})
    2239         {
    2240             my $AName = $TypeInfo{$LibVersion}{$Aid}{"Name"};
    2241            
    2242             if(defined $SkipAnnotationList_User{$AName}) {
    2243                 return 0;
    2244             }
    2245         }
    2246     }
    2247    
    2248     if($AnnotationsListPath)
    2249     {
    2250         my $Annotated = 0;
    2251        
    2252         foreach my $Aid (@{$Ann})
    2253         {
    2254             my $AName = $TypeInfo{$LibVersion}{$Aid}{"Name"};
    2255            
    2256             if(defined $AnnotationList_User{$AName})
    2257             {
    2258                 $Annotated = 1;
    2259                 last;
    2260             }
    2261         }
    2262        
    2263         if(not $Annotated) {
    2264             return 0;
    2265         }
    2266     }
    2267    
    2268     return 1;
    2269 }
    2270 
    2271 sub methodFilter($$)
    2272 {
    2273     my ($Method, $LibVersion) = @_;
    2274    
    2275     if(defined $MethodInfo{$LibVersion}{$Method}{"Dep"}) {
    2276         return 0;
    2277     }
    2278    
    2279     if($MethodInfo{$LibVersion}{$Method}{"Access"}=~/private/)
    2280     { # non-public
    2281         return 0;
    2282     }
    2283    
    2284     my $ClassId = $MethodInfo{$LibVersion}{$Method}{"Class"};
    2285     my %Class = get_Type($ClassId, $LibVersion);
    2286    
    2287     if($Class{"Access"}=~/private/)
    2288     { # skip private classes
    2289         return 0;
    2290     }
    2291    
    2292     my $Package = $MethodInfo{$LibVersion}{$Method}{"Package"};
    2293    
    2294     my @Ann = ();
    2295    
    2296     if(defined $Class{"Annotations"}) {
    2297         @Ann = (@Ann, keys(%{$Class{"Annotations"}}));
    2298     }
    2299    
    2300     if(defined $MethodInfo{$LibVersion}{$Method}{"Annotations"}) {
    2301         @Ann = (@Ann, keys(%{$MethodInfo{$LibVersion}{$Method}{"Annotations"}}));
    2302     }
    2303    
    2304     if(not annotationFilter(\@Ann, $LibVersion)) {
    2305         return 0;
    2306     }
    2307    
    2308     if($ClientPath)
    2309     { # user defined application
    2310         if(not defined $UsedMethods_Client{$Method}
    2311         and not defined $UsedClasses_Client{$Class{"Name"}}) {
    2312             return 0;
    2313         }
    2314     }
    2315    
    2316     if(skipPackage($Package, $LibVersion))
    2317     { # internal packages
    2318         return 0;
    2319     }
    2320    
    2321     if(not classFilter(\%Class, $LibVersion, 0)) {
    2322         return 0;
    2323     }
    2324    
    2325     if(defined $SkipDeprecated)
    2326     {
    2327         if($Class{"Deprecated"})
    2328         { # deprecated class
    2329             return 0;
    2330         }
    2331         if($MethodInfo{$LibVersion}{$Method}{"Deprecated"})
    2332         { # deprecated method
    2333             return 0;
    2334         }
    2335     }
    2336    
    2337     return 1;
    2338 }
    2339 
    2340 sub skipType($)
    2341 {
    2342     my $TName = $_[0];
    2343    
    2344     if(defined $SkipInternalTypes)
    2345     {
    2346         if($TName=~/($SkipInternalTypes)/) {
    2347             return 1;
    2348         }
    2349     }
    2350    
    2351     return 0;
    2352 }
    2353 
    2354 sub skipPackage($$)
    2355 {
    2356     my ($Package, $LibVersion) = @_;
    2357     return 0 if(not $Package);
    2358    
    2359     if(defined $SkipInternalPackages)
    2360     {
    2361         if($Package=~/($SkipInternalPackages)/) {
    2362             return 1;
    2363         }
    2364     }
    2365    
    2366     if(defined $SkipPackages{$LibVersion})
    2367     {
    2368         foreach my $SkipPackage (keys(%{$SkipPackages{$LibVersion}}))
    2369         {
    2370             if($Package=~/\A\Q$SkipPackage\E(\.|\Z)/)
    2371             { # user skipped packages
    2372                 return 1;
    2373             }
    2374         }
    2375     }
    2376    
    2377     if(not defined $KeepInternal)
    2378     {
    2379         my $Note = (not keys %SkippedPackage)?" (use --keep-internal option to check them)":"";
    2380        
    2381         if($Package=~/(\A|\.)(internal|impl|examples)(\.|\Z)/)
    2382         { # internal packages
    2383             if(not $SkippedPackage{$LibVersion}{$2})
    2384             {
    2385                 $SkippedPackage{$LibVersion}{$2} = 1;
    2386                 printMsg("WARNING", "skip \"$2\" packages".$Note);
    2387             }
    2388             return 1;
    2389         }
    2390     }
    2391    
    2392     if(defined $KeepPackages{$LibVersion}
    2393     and my @Keeped = keys(%{$KeepPackages{$LibVersion}}))
    2394     {
    2395         my $UserKeeped = 0;
    2396         foreach my $KeepPackage (@Keeped)
    2397         {
    2398             if($Package=~/\A\Q$KeepPackage\E(\.|\Z)/)
    2399             { # user keeped packages
    2400                 $UserKeeped = 1;
    2401                 last;
    2402             }
    2403         }
    2404         if(not $UserKeeped) {
    2405             return 1;
    2406         }
    2407     }
    2408    
    2409     return 0;
    2410 }
    2411 
    2412 sub get_MSuffix($)
     1441sub getMSuffix($)
    24131442{
    24141443    my $Method = $_[0];
     
    24191448}
    24201449
    2421 sub get_MShort($)
     1450sub getMShort($)
    24221451{
    24231452    my $Method = $_[0];
     
    24361465    {
    24371466        my @Search = ();
    2438         if(get_TypeType($ClassId, $ClassVersion) eq "class")
     1467        if(getTypeType($ClassId, $ClassVersion) eq "class")
    24391468        {
    24401469            if(my $SuperClassId = $TypeInfo{$ClassVersion}{$ClassId}{"SuperClass"}) {
     
    24571486            }
    24581487           
    2459             my $SuperName = get_TypeName($SuperId, $ClassVersion);
     1488            my $SuperName = getTypeName($SuperId, $ClassVersion);
    24601489           
    24611490            if(my $MethodInClass = findMethod_Class($Method, $SuperName, $ClassVersion)) {
     
    24681497    }
    24691498   
    2470     my $TargetSuffix = get_MSuffix($Method);
    2471     my $TargetShortName = get_MShort($Method);
     1499    my $TargetSuffix = getMSuffix($Method);
     1500    my $TargetShortName = getMShort($Method);
    24721501   
    24731502    # search in java.lang.Object
    24741503    foreach my $C (keys(%JavaObjectMethod))
    24751504    {
    2476         if($TargetSuffix eq get_MSuffix($C))
    2477         {
    2478             if($TargetShortName eq get_MShort($C)) {
     1505        if($TargetSuffix eq getMSuffix($C))
     1506        {
     1507            if($TargetShortName eq getMShort($C)) {
    24791508                return $C;
    24801509            }
     
    24881517{
    24891518    my ($Method, $ClassName, $ClassVersion) = @_;
    2490     my $TargetSuffix = get_MSuffix($Method);
    2491     my $TargetShortName = get_MShort($Method);
     1519    my $TargetSuffix = getMSuffix($Method);
     1520    my $TargetShortName = getMShort($Method);
    24921521   
    24931522    if(not defined $Class_Methods{$ClassVersion}{$ClassName}) {
     
    24981527    { # search for method with the same parameters suffix
    24991528        next if($MethodInfo{$ClassVersion}{$Candidate}{"Constructor"});
    2500         if($TargetSuffix eq get_MSuffix($Candidate))
    2501         {
    2502             if($TargetShortName eq get_MShort($Candidate)) {
     1529        if($TargetSuffix eq getMSuffix($Candidate))
     1530        {
     1531            if($TargetShortName eq getMShort($Candidate)) {
    25031532                return $Candidate;
    25041533            }
     
    25091538}
    25101539
    2511 sub prepareMethods($)
    2512 {
    2513     my $LibVersion = $_[0];
    2514     foreach my $Method (keys(%{$MethodInfo{$LibVersion}}))
    2515     {
    2516         if($MethodInfo{$LibVersion}{$Method}{"Access"}!~/private/)
    2517         {
    2518             if($MethodInfo{$LibVersion}{$Method}{"Constructor"}) {
    2519                 registerUsage($MethodInfo{$LibVersion}{$Method}{"Class"}, $LibVersion);
     1540sub prepareData($)
     1541{
     1542    my $LVer = $_[0];
     1543   
     1544    if(my $MUsed = $In::API{$LVer}{"MethodUsed"})
     1545    {
     1546        foreach my $M_Id (keys(%{$MUsed}))
     1547        {
     1548            my $Name = $MUsed->{$M_Id}{"Name"};
     1549            $MethodUsed{$LVer}{$Name} = $MUsed->{$M_Id}{"Used"};
     1550        }
     1551    }
     1552   
     1553    foreach my $TypeId (keys(%{$TypeInfo{$LVer}}))
     1554    {
     1555        my $TypeAttr = $TypeInfo{$LVer}{$TypeId};
     1556        my $TName = $TypeAttr->{"Name"};
     1557       
     1558        $TName_Tid{$LVer}{$TName} = $TypeId;
     1559       
     1560        if(not $TypeAttr->{"Dep"})
     1561        {
     1562            if(my $Archive = $TypeAttr->{"Archive"}) {
     1563                $LibArchives{$LVer}{$Archive} = 1;
     1564            }
     1565        }
     1566       
     1567        foreach my $FieldName (keys(%{$TypeAttr->{"Fields"}}))
     1568        {
     1569            if($TypeAttr->{"Fields"}{$FieldName}{"Access"}=~/public|protected/) {
     1570                $Class_Fields{$LVer}{$TName}{$FieldName} = $TypeAttr->{"Fields"}{$FieldName}{"Type"};
     1571            }
     1572        }
     1573    }
     1574   
     1575    foreach my $Method (keys(%{$MethodInfo{$LVer}}))
     1576    {
     1577        my $Name = $MethodInfo{$LVer}{$Method}{"Name"};
     1578        $MethodInfo{$LVer}{$Name} = delete($MethodInfo{$LVer}{$Method});
     1579    }
     1580   
     1581    foreach my $Method (keys(%{$MethodInfo{$LVer}}))
     1582    {
     1583        my $MAttr = $MethodInfo{$LVer}{$Method};
     1584       
     1585        $MAttr->{"Signature"} = getSignature($Method, $LVer, "Full");
     1586       
     1587        if(my $ClassId = $MAttr->{"Class"}
     1588        and $MAttr->{"Access"}=~/public|protected/)
     1589        {
     1590            my $CName = getTypeName($ClassId, $LVer);
     1591            $Class_Methods{$LVer}{$CName}{$Method} = 1;
     1592            if($MAttr->{"Abstract"}) {
     1593                $Class_AbstractMethods{$LVer}{$CName}{$Method} = 1;
     1594            }
     1595        }
     1596       
     1597        if($MAttr->{"Access"}!~/private/)
     1598        {
     1599            if($MAttr->{"Constructor"}) {
     1600                registerUsage($MAttr->{"Class"}, $LVer);
    25201601            }
    25211602            else {
    2522                 registerUsage($MethodInfo{$LibVersion}{$Method}{"Return"}, $LibVersion);
     1603                registerUsage($MAttr->{"Return"}, $LVer);
    25231604            }
    25241605        }
     
    25421623       
    25431624        my $ClassId1 = $MethodInfo{1}{$Method}{"Class"};
    2544         my %Class1 = get_Type($ClassId1, 1);
    2545        
    2546         $CheckedTypes{$Class1{"Name"}} = 1;
     1625        my $Class1_Name = getTypeName($ClassId1, 1);
     1626        my $Class1_Type = getTypeType($ClassId1, 1);
     1627       
     1628        $CheckedTypes{$Class1_Name} = 1;
    25471629        $CheckedMethods{$Method} = 1;
    25481630       
    2549         my %Class2 = get_Type($MethodInfo{2}{$Method}{"Class"}, 2);
    25501631        if(not $MethodInfo{1}{$Method}{"Static"}
    2551         and $Class1{"Type"} eq "class" and not $Class_Constructed{1}{$ClassId1})
     1632        and $Class1_Type eq "class" and not $Class_Constructed{1}{$ClassId1})
    25521633        { # class cannot be constructed or inherited by clients
    25531634          # non-static method cannot be called
    25541635            next;
    25551636        }
     1637       
    25561638        # checking attributes
    25571639        if(not $MethodInfo{1}{$Method}{"Static"}
     
    25631645            %{$CompatProblems{$Method}{"Method_Became_NonStatic"}{""}} = ();
    25641646        }
     1647       
    25651648        if(not $MethodInfo{1}{$Method}{"Synchronized"}
    25661649        and $MethodInfo{2}{$Method}{"Synchronized"}) {
     
    25711654            %{$CompatProblems{$Method}{"Method_Became_NonSynchronized"}{""}} = ();
    25721655        }
     1656       
    25731657        if(not $MethodInfo{1}{$Method}{"Final"}
    25741658        and $MethodInfo{2}{$Method}{"Final"})
     
    25811665            }
    25821666        }
     1667       
    25831668        my $Access1 = $MethodInfo{1}{$Method}{"Access"};
    25841669        my $Access2 = $MethodInfo{2}{$Method}{"Access"};
     1670       
    25851671        if($Access1 eq "public" and $Access2=~/protected|private/
    25861672        or $Access1 eq "protected" and $Access2=~/private/)
     
    25881674            %{$CompatProblems{$Method}{"Changed_Method_Access"}{""}} = (
    25891675                "Old_Value"=>$Access1,
    2590                 "New_Value"=>$Access2  );
    2591         }
    2592         if($Class1{"Type"} eq "class"
    2593         and $Class2{"Type"} eq "class")
     1676                "New_Value"=>$Access2);
     1677        }
     1678       
     1679        my $Class2_Type = getTypeType($MethodInfo{2}{$Method}{"Class"}, 2);
     1680       
     1681        if($Class1_Type eq "class"
     1682        and $Class2_Type eq "class")
    25941683        {
    25951684            if(not $MethodInfo{1}{$Method}{"Abstract"}
     
    25971686            {
    25981687                %{$CompatProblems{$Method}{"Method_Became_Abstract"}{""}} = ();
    2599                 %{$CompatProblems{$Method}{"Class_Method_Became_Abstract"}{"this.".get_SFormat($Method)}} = (
    2600                     "Type_Name"=>$Class1{"Name"},
    2601                     "Target"=>$Method  );
     1688                %{$CompatProblems{$Method}{"Class_Method_Became_Abstract"}{"this.".getSFormat($Method)}} = (
     1689                    "Type_Name"=>$Class1_Name,
     1690                    "Target"=>$Method);
    26021691            }
    26031692            elsif($MethodInfo{1}{$Method}{"Abstract"}
     
    26051694            {
    26061695                %{$CompatProblems{$Method}{"Method_Became_NonAbstract"}{""}} = ();
    2607                 %{$CompatProblems{$Method}{"Class_Method_Became_NonAbstract"}{"this.".get_SFormat($Method)}} = (
    2608                     "Type_Name"=>$Class1{"Name"},
    2609                     "Target"=>$Method  );
    2610             }
    2611         }
    2612         elsif($Class1{"Type"} eq "interface"
    2613         and $Class2{"Type"} eq "interface")
     1696                %{$CompatProblems{$Method}{"Class_Method_Became_NonAbstract"}{"this.".getSFormat($Method)}} = (
     1697                    "Type_Name"=>$Class1_Name,
     1698                    "Target"=>$Method);
     1699            }
     1700        }
     1701        elsif($Class1_Type eq "interface"
     1702        and $Class2_Type eq "interface")
    26141703        {
    26151704            if(not $MethodInfo{1}{$Method}{"Abstract"}
     
    26171706            {
    26181707                %{$CompatProblems{$Method}{"Method_Became_NonDefault"}{""}} = ();
    2619                 %{$CompatProblems{$Method}{"Interface_Method_Became_NonDefault"}{"this.".get_SFormat($Method)}} = (
    2620                     "Type_Name"=>$Class1{"Name"},
    2621                     "Target"=>$Method  );
     1708                %{$CompatProblems{$Method}{"Interface_Method_Became_NonDefault"}{"this.".getSFormat($Method)}} = (
     1709                    "Type_Name"=>$Class1_Name,
     1710                    "Target"=>$Method);
    26221711            }
    26231712            elsif($MethodInfo{1}{$Method}{"Abstract"}
     
    26251714            {
    26261715                %{$CompatProblems{$Method}{"Method_Became_Default"}{""}} = ();
    2627                 %{$CompatProblems{$Method}{"Interface_Method_Became_Default"}{"this.".get_SFormat($Method)}} = (
    2628                     "Type_Name"=>$Class1{"Name"},
    2629                     "Target"=>$Method  );
    2630             }
    2631         }
    2632        
    2633         my %Exceptions_Old = map {get_TypeName($_, 1) => $_} keys(%{$MethodInfo{1}{$Method}{"Exceptions"}});
    2634         my %Exceptions_New = map {get_TypeName($_, 2) => $_} keys(%{$MethodInfo{2}{$Method}{"Exceptions"}});
     1716                %{$CompatProblems{$Method}{"Interface_Method_Became_Default"}{"this.".getSFormat($Method)}} = (
     1717                    "Type_Name"=>$Class1_Name,
     1718                    "Target"=>$Method);
     1719            }
     1720        }
     1721       
     1722        my %Exceptions_Old = map {getTypeName($_, 1) => $_} keys(%{$MethodInfo{1}{$Method}{"Exceptions"}});
     1723        my %Exceptions_New = map {getTypeName($_, 2) => $_} keys(%{$MethodInfo{2}{$Method}{"Exceptions"}});
    26351724        foreach my $Exception (keys(%Exceptions_Old))
    26361725        {
    26371726            if(not $Exceptions_New{$Exception})
    26381727            {
    2639                 my %ExceptionType = get_Type($Exceptions_Old{$Exception}, 1);
    2640                 my $SuperClass = $ExceptionType{"SuperClass"};
     1728                my $EType = getType($Exceptions_Old{$Exception}, 1);
     1729                my $SuperClass = $EType->{"SuperClass"};
     1730               
    26411731                if($KnownRuntimeExceptions{$Exception}
    2642                 or defined $SuperClass and get_TypeName($SuperClass, 1) eq "java.lang.RuntimeException")
     1732                or defined $SuperClass and getTypeName($SuperClass, 1) eq "java.lang.RuntimeException")
    26431733                {
    26441734                    if(not $MethodInfo{1}{$Method}{"Abstract"}
    26451735                    and not $MethodInfo{2}{$Method}{"Abstract"})
    26461736                    {
    2647                         %{$CompatProblems{$Method}{"Removed_Unchecked_Exception"}{"this.".get_SFormat($Exception)}} = (
    2648                             "Type_Name"=>$Class1{"Name"},
    2649                             "Target"=>$Exception  );
     1737                        %{$CompatProblems{$Method}{"Removed_Unchecked_Exception"}{"this.".getSFormat($Exception)}} = (
     1738                            "Type_Name"=>$Class1_Name,
     1739                            "Target"=>$Exception);
    26501740                    }
    26511741                }
     
    26551745                    and $MethodInfo{2}{$Method}{"Abstract"})
    26561746                    {
    2657                         %{$CompatProblems{$Method}{"Abstract_Method_Removed_Checked_Exception"}{"this.".get_SFormat($Exception)}} = (
    2658                             "Type_Name"=>$Class1{"Name"},
    2659                             "Target"=>$Exception  );
     1747                        %{$CompatProblems{$Method}{"Abstract_Method_Removed_Checked_Exception"}{"this.".getSFormat($Exception)}} = (
     1748                            "Type_Name"=>$Class1_Name,
     1749                            "Target"=>$Exception);
    26601750                    }
    26611751                    else
    26621752                    {
    2663                         %{$CompatProblems{$Method}{"NonAbstract_Method_Removed_Checked_Exception"}{"this.".get_SFormat($Exception)}} = (
    2664                             "Type_Name"=>$Class1{"Name"},
    2665                             "Target"=>$Exception  );
    2666                     }
    2667                 }
    2668             }
    2669         }
     1753                        %{$CompatProblems{$Method}{"NonAbstract_Method_Removed_Checked_Exception"}{"this.".getSFormat($Exception)}} = (
     1754                            "Type_Name"=>$Class1_Name,
     1755                            "Target"=>$Exception);
     1756                    }
     1757                }
     1758            }
     1759        }
     1760       
    26701761        foreach my $Exception (keys(%Exceptions_New))
    26711762        {
    26721763            if(not $Exceptions_Old{$Exception})
    26731764            {
    2674                 my %ExceptionType = get_Type($Exceptions_New{$Exception}, 2);
    2675                 my $SuperClass = $ExceptionType{"SuperClass"};
     1765                my $EType = getType($Exceptions_New{$Exception}, 2);
     1766                my $SuperClass = $EType->{"SuperClass"};
     1767               
    26761768                if($KnownRuntimeExceptions{$Exception}
    2677                 or defined $SuperClass and get_TypeName($SuperClass, 2) eq "java.lang.RuntimeException")
     1769                or defined $SuperClass and getTypeName($SuperClass, 2) eq "java.lang.RuntimeException")
    26781770                {
    26791771                    if(not $MethodInfo{1}{$Method}{"Abstract"}
    26801772                    and not $MethodInfo{2}{$Method}{"Abstract"})
    26811773                    {
    2682                         %{$CompatProblems{$Method}{"Added_Unchecked_Exception"}{"this.".get_SFormat($Exception)}} = (
    2683                             "Type_Name"=>$Class1{"Name"},
    2684                             "Target"=>$Exception  );
     1774                        %{$CompatProblems{$Method}{"Added_Unchecked_Exception"}{"this.".getSFormat($Exception)}} = (
     1775                            "Type_Name"=>$Class1_Name,
     1776                            "Target"=>$Exception);
    26851777                    }
    26861778                }
     
    26901782                    and $MethodInfo{2}{$Method}{"Abstract"})
    26911783                    {
    2692                         %{$CompatProblems{$Method}{"Abstract_Method_Added_Checked_Exception"}{"this.".get_SFormat($Exception)}} = (
    2693                             "Type_Name"=>$Class1{"Name"},
    2694                             "Target"=>$Exception  );
     1784                        %{$CompatProblems{$Method}{"Abstract_Method_Added_Checked_Exception"}{"this.".getSFormat($Exception)}} = (
     1785                            "Type_Name"=>$Class1_Name,
     1786                            "Target"=>$Exception);
    26951787                    }
    26961788                    else
    26971789                    {
    2698                         %{$CompatProblems{$Method}{"NonAbstract_Method_Added_Checked_Exception"}{"this.".get_SFormat($Exception)}} = (
    2699                             "Type_Name"=>$Class1{"Name"},
    2700                             "Target"=>$Exception  );
     1790                        %{$CompatProblems{$Method}{"NonAbstract_Method_Added_Checked_Exception"}{"this.".getSFormat($Exception)}} = (
     1791                            "Type_Name"=>$Class1_Name,
     1792                            "Target"=>$Exception);
    27011793                    }
    27021794                }
     
    27791871    my ($Type1_Id, $Type2_Id, $Prefix) = @_;
    27801872    my %LocalProblems = ();
    2781     my %Type1 = get_Type($Type1_Id, 1);
    2782     my %Type2 = get_Type($Type2_Id, 2);
    2783     my %Type1_Base = ($Type1{"Type"} eq "array")?get_OneStep_BaseType($Type1_Id, 1):get_BaseType($Type1_Id, 1);
    2784     my %Type2_Base = ($Type2{"Type"} eq "array")?get_OneStep_BaseType($Type2_Id, 2):get_BaseType($Type2_Id, 2);
    2785     return () if(not $Type1{"Name"} or not $Type2{"Name"});
    2786     return () if(not $Type1_Base{"Name"} or not $Type2_Base{"Name"});
    2787     if($Type1_Base{"Name"} ne $Type2_Base{"Name"} and $Type1{"Name"} eq $Type2{"Name"})
     1873   
     1874    my $Type1 = getType($Type1_Id, 1);
     1875    my $Type2 = getType($Type2_Id, 2);
     1876   
     1877    my $Type1_Name = $Type1->{"Name"};
     1878    my $Type2_Name = $Type2->{"Name"};
     1879   
     1880    my $Type1_Base = undef;
     1881    my $Type2_Base = undef;
     1882   
     1883    if($Type1->{"Type"} eq "array") {
     1884        $Type1_Base = getOneStepBaseType($Type1_Id, 1);
     1885    }
     1886    else {
     1887        $Type1_Base = getBaseType($Type1_Id, 1);
     1888    }
     1889   
     1890    if($Type2->{"Type"} eq "array") {
     1891        $Type2_Base = getOneStepBaseType($Type2_Id, 2);
     1892    }
     1893    else {
     1894        $Type2_Base = getBaseType($Type2_Id, 2);
     1895    }
     1896   
     1897    return () if(not $Type1_Name or not $Type2_Name);
     1898    return () if(not $Type1_Base->{"Name"} or not $Type2_Base->{"Name"});
     1899    if($Type1_Base->{"Name"} ne $Type2_Base->{"Name"} and $Type1_Name eq $Type2_Name)
    27881900    {# base type change
    27891901        %{$LocalProblems{"Changed_".$Prefix."_BaseType"}}=(
    2790             "Old_Value"=>$Type1_Base{"Name"},
    2791             "New_Value"=>$Type2_Base{"Name"} );
    2792     }
    2793     elsif($Type1{"Name"} ne $Type2{"Name"})
     1902            "Old_Value"=>$Type1_Base->{"Name"},
     1903            "New_Value"=>$Type2_Base->{"Name"});
     1904    }
     1905    elsif($Type1_Name ne $Type2_Name)
    27941906    {# type change
    27951907        %{$LocalProblems{"Changed_".$Prefix."_Type"}}=(
    2796             "Old_Value"=>$Type1{"Name"},
    2797             "New_Value"=>$Type2{"Name"} );
     1908            "Old_Value"=>$Type1_Name,
     1909            "New_Value"=>$Type2_Name);
    27981910    }
    27991911    return %LocalProblems;
    28001912}
    28011913
    2802 sub htmlSpecChars($)
     1914sub specChars($)
    28031915{
    28041916    my $Str = $_[0];
     
    28201932}
    28211933
    2822 sub black_Name($$)
     1934sub blackName($)
     1935{
     1936    my $N = $_[0];
     1937    return "<span class='iname_b'>".$N."</span>";
     1938}
     1939
     1940sub highLight_ItalicColor($$)
    28231941{
    28241942    my ($M, $V) = @_;
    2825     return "<span class='iname_b'>".highLight_Signature($M, $V)."</span>";
    2826 }
    2827 
    2828 sub black_Name_S($)
    2829 {
    2830     my $Name = $_[0];
    2831     $Name=~s!\A(\w+)!<span class='iname_b'>$1</span>&#160;!g;
    2832     return $Name;
    2833 }
    2834 
    2835 sub highLight_Signature($$)
    2836 {
    2837     my ($M, $V) = @_;
    2838     return get_Signature($M, $V, "Class|HTML|Italic");
    2839 }
    2840 
    2841 sub highLight_Signature_Italic_Color($$)
    2842 {
    2843     my ($M, $V) = @_;
    2844     return get_Signature($M, $V, "Full|HTML|Italic|Color");
    2845 }
    2846 
    2847 sub get_Signature($$$)
    2848 {
    2849     my ($Method, $LibVersion, $Kind) = @_;
    2850     if(defined $Cache{"get_Signature"}{$LibVersion}{$Method}{$Kind}) {
    2851         return $Cache{"get_Signature"}{$LibVersion}{$Method}{$Kind};
     1943    return getSignature($M, $V, "Full|HTML|Italic|Color");
     1944}
     1945
     1946sub getSignature($$$)
     1947{
     1948    my ($Method, $LVer, $Kind) = @_;
     1949    if(defined $Cache{"getSignature"}{$LVer}{$Method}{$Kind}) {
     1950        return $Cache{"getSignature"}{$LVer}{$Method}{$Kind};
    28521951    }
    28531952   
    28541953    # settings
    28551954    my ($Full, $Html, $Simple, $Italic, $Color,
    2856     $ShowParams, $ShowClass, $ShowAttr, $Target) = (0, 0, 0, 0, 0, 0, 0, 0, undef);
     1955    $ShowParams, $ShowClass, $ShowAttr, $Desc, $Target) = (0, 0, 0, 0, 0, 0, 0, 0, 0, undef);
    28571956   
    28581957    if($Kind=~/Full/) {
     
    28831982        $ShowAttr = 1;
    28841983    }
    2885    
    2886     if(not defined $MethodInfo{$LibVersion}{$Method}{"ShortName"})
     1984    if($Kind=~/Desc/) {
     1985        $Desc = 1;
     1986    }
     1987   
     1988    if(not defined $MethodInfo{$LVer}{$Method}{"ShortName"})
    28871989    { # from java.lang.Object
    28881990        if($Html or $Simple) {
    2889             return htmlSpecChars($Method);
    2890         }
    2891         else
    2892         {
     1991            return specChars($Method);
     1992        }
     1993        else {
    28931994            return $Method;
    28941995        }
    28951996    }
    28961997   
    2897     my $Signature = $MethodInfo{$LibVersion}{$Method}{"ShortName"};
     1998    my $Signature = $MethodInfo{$LVer}{$Method}{"ShortName"};
    28981999    if($Full or $ShowClass)
    28992000    {
    2900         my $Class = get_TypeName($MethodInfo{$LibVersion}{$Method}{"Class"}, $LibVersion);
    2901        
    2902         if($HideTemplates) {
     2001        my $Class = getTypeName($MethodInfo{$LVer}{$Method}{"Class"}, $LVer);
     2002       
     2003        if($In::Opt{"HideTemplates"}) {
    29032004            $Class=~s/<.*>//g;
    29042005        }
    29052006       
    29062007        if($Html) {
    2907             $Class = htmlSpecChars($Class);
     2008            $Class = specChars($Class);
    29082009        }
    29092010       
     
    29122013    my @Params = ();
    29132014   
    2914     if(defined $MethodInfo{$LibVersion}{$Method}{"Param"})
     2015    if(defined $MethodInfo{$LVer}{$Method}{"Param"})
    29152016    {
    29162017        foreach my $PPos (sort {int($a)<=>int($b)}
    2917         keys(%{$MethodInfo{$LibVersion}{$Method}{"Param"}}))
    2918         {
    2919             my $PTid = $MethodInfo{$LibVersion}{$Method}{"Param"}{$PPos}{"Type"};
    2920             if(my $PTName = get_TypeName($PTid, $LibVersion))
    2921             {
    2922                 if($HideTemplates) {
     2018        keys(%{$MethodInfo{$LVer}{$Method}{"Param"}}))
     2019        {
     2020            my $PTid = $MethodInfo{$LVer}{$Method}{"Param"}{$PPos}{"Type"};
     2021            if(my $PTName = getTypeName($PTid, $LVer))
     2022            {
     2023                if($In::Opt{"HideTemplates"}) {
    29232024                    $PTName=~s/<.*>//g;
    29242025                }
    29252026               
    2926                 if(not $ShowPackages) {
     2027                if(not $In::Opt{"ShowPackages"}) {
    29272028                    $PTName=~s/(\A|\<\s*|\,\s*)[a-z0-9\.]+\./$1/g;
    29282029                }
    29292030               
    29302031                if($Html) {
    2931                     $PTName = htmlSpecChars($PTName);
     2032                    $PTName = specChars($PTName);
    29322033                }
    29332034               
    29342035                if($Full or $ShowParams)
    29352036                {
    2936                     my $PName = $MethodInfo{$LibVersion}{$Method}{"Param"}{$PPos}{"Name"};
     2037                    my $PName = $MethodInfo{$LVer}{$Method}{"Param"}{$PPos}{"Name"};
    29372038                   
    29382039                    if($Simple) {
     
    29712072    {
    29722073        $Signature .= "&#160;";
    2973         $Signature .= "<span class='sym_p'>";
     2074        if($Desc) {
     2075            $Signature .= "<span class='sym_pd'>";
     2076        }
     2077        else {
     2078            $Signature .= "<span class='sym_p'>";
     2079        }
    29742080        if(@Params)
    29752081        {
     
    30132119    if($Full or $ShowAttr)
    30142120    {
    3015         if($MethodInfo{$LibVersion}{$Method}{"Static"}) {
     2121        if($MethodInfo{$LVer}{$Method}{"Static"}) {
    30162122            $Signature .= " [static]";
    30172123        }
    3018         elsif($MethodInfo{$LibVersion}{$Method}{"Abstract"}) {
     2124        elsif($MethodInfo{$LVer}{$Method}{"Abstract"}) {
    30192125            $Signature .= " [abstract]";
    30202126        }
     
    30232129    if($Full)
    30242130    {
    3025         if($ShowAccess)
    3026         {
    3027             if(my $Access = $MethodInfo{$LibVersion}{$Method}{"Access"})
     2131        if($In::Opt{"ShowAccess"})
     2132        {
     2133            if(my $Access = $MethodInfo{$LVer}{$Method}{"Access"})
    30282134            {
    30292135                if($Access ne "public") {
     
    30332139        }
    30342140       
    3035         if(my $ReturnId = $MethodInfo{$LibVersion}{$Method}{"Return"})
    3036         {
    3037             my $RName = get_TypeName($ReturnId, $LibVersion);
     2141        if(my $ReturnId = $MethodInfo{$LVer}{$Method}{"Return"})
     2142        {
     2143            my $RName = getTypeName($ReturnId, $LVer);
    30382144           
    3039             if($HideTemplates) {
     2145            if($In::Opt{"HideTemplates"}) {
    30402146                $RName=~s/<.*>//g;
    30412147            }
    30422148           
    3043             if(not $ShowPackages) {
     2149            if(not $In::Opt{"ShowPackages"}) {
    30442150                $RName=~s/(\A|\<\s*|\,\s*)[a-z0-9\.]+\./$1/g;
    30452151            }
    30462152           
    30472153            if($Simple) {
    3048                 $Signature .= " <b>:</b> ".htmlSpecChars($RName);
     2154                $Signature .= " <b>:</b> ".specChars($RName);
    30492155            }
    30502156            elsif($Html) {
    3051                 $Signature .= "<span class='sym_p nowrap'> &#160;<b>:</b>&#160;&#160;".htmlSpecChars($RName)."</span>";
     2157                $Signature .= "<span class='sym_p nowrap'> &#160;<b>:</b>&#160;&#160;".specChars($RName)."</span>";
    30522158            }
    30532159            else {
     
    30562162        }
    30572163       
    3058         if(not $SkipDeprecated)
    3059         {
    3060             if($MethodInfo{$LibVersion}{$Method}{"Deprecated"}) {
     2164        if(not $In::Opt{"SkipDeprecated"})
     2165        {
     2166            if($MethodInfo{$LVer}{$Method}{"Deprecated"}) {
    30612167                $Signature .= " *DEPRECATED*";
    30622168            }
     
    30682174    if($Html)
    30692175    {
    3070         if(not $SkipDeprecated) {
     2176        if(not $In::Opt{"SkipDeprecated"}) {
    30712177            $Signature=~s!(\*deprecated\*)!<span class='deprecated'>$1</span>!ig;
    30722178        }
     
    30842190    }
    30852191   
    3086     return ($Cache{"get_Signature"}{$LibVersion}{$Method}{$Kind} = $Signature);
    3087 }
    3088 
    3089 sub checkJavaCompiler($)
    3090 { # check javac: compile simple program
    3091     my $Cmd = $_[0];
    3092    
    3093     if(not $Cmd) {
    3094         return;
    3095     }
    3096    
    3097     writeFile($TMP_DIR."/test_javac/Simple.java",
    3098     "public class Simple {
    3099         public Integer f;
    3100         public void method(Integer p) { };
    3101     }");
    3102     chdir($TMP_DIR."/test_javac");
    3103     system("$Cmd Simple.java 2>errors.txt");
    3104     chdir($ORIG_DIR);
    3105     if($?)
    3106     {
    3107         my $Msg = "something is going wrong with the Java compiler (javac):\n";
    3108         my $Err = readFile($TMP_DIR."/test_javac/errors.txt");
    3109         $Msg .= $Err;
    3110         if($Err=~/elf\/start\.S/ and $Err=~/undefined\s+reference\s+to/)
    3111         { # /usr/lib/gcc/i586-suse-linux/4.5/../../../crt1.o: In function _start:
    3112           # /usr/src/packages/BUILD/glibc-2.11.3/csu/../sysdeps/i386/elf/start.S:115: undefined reference to main
    3113             $Msg .= "\nDid you install a JDK-devel package?";
    3114         }
    3115         exitStatus("Error", $Msg);
    3116     }
    3117 }
    3118 
    3119 sub runTests($$$$)
    3120 {
    3121     my ($TestsPath, $PackageName, $Path_v1, $Path_v2) = @_;
    3122     # compile with old version of package
    3123     my $JavacCmd = get_CmdPath("javac");
    3124     if(not $JavacCmd) {
    3125         exitStatus("Not_Found", "can't find \"javac\" compiler");
    3126     }
    3127     my $JavaCmd = get_CmdPath("java");
    3128     if(not $JavaCmd) {
    3129         exitStatus("Not_Found", "can't find \"java\" command");
    3130     }
    3131     mkpath($TestsPath."/$PackageName/");
    3132     foreach my $ClassPath (cmd_find($Path_v1,"","*\.class",""))
    3133     {# create a compile-time package copy
    3134         copy($ClassPath, $TestsPath."/$PackageName/");
    3135     }
    3136     chdir($TestsPath);
    3137     system($JavacCmd." -g *.java");
    3138     chdir($ORIG_DIR);
    3139     foreach my $TestSrc (cmd_find($TestsPath,"","*\.java",""))
    3140     { # remove test source
    3141         unlink($TestSrc);
    3142     }
    3143    
    3144     my $PkgPath = $TestsPath."/".$PackageName;
    3145     if(-d $PkgPath) {
    3146         rmtree($PkgPath);
    3147     }
    3148     mkpath($PkgPath);
    3149     foreach my $ClassPath (cmd_find($Path_v2,"","*\.class",""))
    3150     {# create a run-time package copy
    3151         copy($ClassPath, $PkgPath."/");
    3152     }
    3153     my $TEST_REPORT = "";
    3154     foreach my $TestPath (cmd_find($TestsPath,"","*\.class",1))
    3155     {# run tests
    3156         my $Name = get_filename($TestPath);
    3157         $Name=~s/\.class\Z//g;
    3158         chdir($TestsPath);
    3159         system($JavaCmd." $Name >result.txt 2>&1");
    3160         chdir($ORIG_DIR);
    3161         my $Result = readFile($TestsPath."/result.txt");
    3162         unlink($TestsPath."/result.txt");
    3163         $TEST_REPORT .= "TEST CASE: $Name\n";
    3164         if($Result) {
    3165             $TEST_REPORT .= "RESULT: FAILED\n";
    3166             $TEST_REPORT .= "OUTPUT:\n$Result\n";
    3167         }
    3168         else {
    3169             $TEST_REPORT .= "RESULT: SUCCESS\n";
    3170         }
    3171         $TEST_REPORT .= "\n";
    3172     }
    3173     writeFile("$TestsPath/Journal.txt", $TEST_REPORT);
    3174    
    3175     if(-d $PkgPath) {
    3176         rmtree($PkgPath);
    3177     }
    3178 }
    3179 
    3180 sub compileJavaLib($$$)
    3181 {
    3182     my ($LibName, $BuildRoot1, $BuildRoot2) = @_;
    3183     my $JavacCmd = get_CmdPath("javac");
    3184     if(not $JavacCmd) {
    3185         exitStatus("Not_Found", "can't find \"javac\" compiler");
    3186     }
    3187     checkJavaCompiler($JavacCmd);
    3188     my $JarCmd = get_CmdPath("jar");
    3189     if(not $JarCmd) {
    3190         exitStatus("Not_Found", "can't find \"jar\" command");
    3191     }
    3192     writeFile("$BuildRoot1/MANIFEST.MF", "Implementation-Version: 1.0\n");
    3193     # space before value, new line
    3194     writeFile("$BuildRoot2/MANIFEST.MF", "Implementation-Version: 2.0\n");
    3195     my (%SrcDir1, %SrcDir2) = ();
    3196     foreach my $Path (cmd_find($BuildRoot1,"f","*.java","")) {
    3197         $SrcDir1{get_dirname($Path)} = 1;
    3198     }
    3199     foreach my $Path (cmd_find($BuildRoot2,"f","*.java","")) {
    3200         $SrcDir2{get_dirname($Path)} = 1;
    3201     }
    3202     # build classes v.1
    3203     foreach my $Dir (keys(%SrcDir1))
    3204     {
    3205         chdir($Dir);
    3206         system("$JavacCmd -g *.java");
    3207         chdir($ORIG_DIR);
    3208         if($?) {
    3209             exitStatus("Error", "can't compile classes v.1");
    3210         }
    3211     }
    3212     # create java archive v.1
    3213     chdir($BuildRoot1);
    3214     system("$JarCmd -cmf MANIFEST.MF $LibName.jar TestPackage");
    3215     chdir($ORIG_DIR);
    3216    
    3217     # build classes v.2
    3218     foreach my $Dir (keys(%SrcDir2))
    3219     {
    3220         chdir($Dir);
    3221         system("$JavacCmd -g *.java");
    3222         chdir($ORIG_DIR);
    3223         if($?) {
    3224             exitStatus("Error", "can't compile classes v.2");
    3225         }
    3226     }
    3227     # create java archive v.2
    3228     chdir($BuildRoot2);
    3229     system("$JarCmd -cmf MANIFEST.MF $LibName.jar TestPackage");
    3230     chdir($ORIG_DIR);
    3231    
    3232     foreach my $SrcPath (cmd_find($BuildRoot1,"","*\.java","")) {
    3233         unlink($SrcPath);
    3234     }
    3235     foreach my $SrcPath (cmd_find($BuildRoot2,"","*\.java","")) {
    3236         unlink($SrcPath);
    3237     }
    3238     return 1;
    3239 }
    3240 
    3241 sub readLineNum($$)
    3242 {
    3243     my ($Path, $Num) = @_;
    3244     return "" if(not $Path or not -f $Path);
    3245     open (FILE, $Path);
    3246     foreach (1 ... $Num) {
    3247         <FILE>;
    3248     }
    3249     my $Line = <FILE>;
    3250     close(FILE);
    3251     return $Line;
    3252 }
    3253 
    3254 sub readAttributes($$)
    3255 {
    3256     my ($Path, $Num) = @_;
    3257     return () if(not $Path or not -f $Path);
    3258     my %Attributes = ();
    3259     if(readLineNum($Path, $Num)=~/<!--\s+(.+)\s+-->/)
    3260     {
    3261         foreach my $AttrVal (split(/;/, $1))
    3262         {
    3263             if($AttrVal=~/(.+):(.+)/)
    3264             {
    3265                 my ($Name, $Value) = ($1, $2);
    3266                 $Attributes{$Name} = $Value;
    3267             }
    3268         }
    3269     }
    3270     return \%Attributes;
    3271 }
    3272 
    3273 sub runChecker($$$)
    3274 {
    3275     my ($LibName, $Path1, $Path2) = @_;
    3276     writeFile("$LibName/v1.xml", "
    3277         <version>
    3278             1.0
    3279         </version>
    3280         <archives>
    3281             ".get_abs_path($Path1)."
    3282         </archives>");
    3283     writeFile("$LibName/v2.xml", "
    3284         <version>
    3285             2.0
    3286         </version>
    3287         <archives>
    3288             ".get_abs_path($Path2)."
    3289         </archives>");
    3290     my $Cmd = "perl $0 -l $LibName $LibName/v1.xml $LibName/v2.xml";
    3291     if($Quick) {
    3292         $Cmd .= " -quick";
    3293     }
    3294     if(defined $SkipDeprecated) {
    3295         $Cmd .= " -skip-deprecated";
    3296     }
    3297     if(defined $OldStyle) {
    3298         $Cmd .= " -old-style";
    3299     }
    3300     writeFile($TMP_DIR."/skip-annotations.list", "TestPackage.Beta");
    3301     $Cmd .= " -skip-annotations-list ".$TMP_DIR."/skip-annotations.list";
    3302     if($Debug)
    3303     {
    3304         $Cmd .= " -debug";
    3305         printMsg("INFO", "running $Cmd");
    3306     }
    3307     system($Cmd);
    3308     my $Report = "compat_reports/$LibName/1.0_to_2.0/compat_report.html";
    3309     # Binary
    3310     my $BReport = readAttributes($Report, 0);
    3311     my $NProblems = $BReport->{"type_problems_high"}+$BReport->{"type_problems_medium"};
    3312     $NProblems += $BReport->{"method_problems_high"}+$BReport->{"method_problems_medium"};
    3313     $NProblems += $BReport->{"removed"};
    3314     # Source
    3315     my $SReport = readAttributes($Report, 1);
    3316     $NProblems += $SReport->{"type_problems_high"}+$SReport->{"type_problems_medium"};
    3317     $NProblems += $SReport->{"method_problems_high"}+$SReport->{"method_problems_medium"};
    3318     $NProblems += $SReport->{"removed"};
    3319     if($NProblems>=100) {
    3320         printMsg("INFO", "test result: SUCCESS ($NProblems breaks found)\n");
    3321     }
    3322     else {
    3323         printMsg("ERROR", "test result: FAILED ($NProblems breaks found)\n");
    3324     }
    3325 }
    3326 
    3327 sub writeFile($$)
    3328 {
    3329     my ($Path, $Content) = @_;
    3330     return if(not $Path);
    3331     if(my $Dir = get_dirname($Path)) {
    3332         mkpath($Dir);
    3333     }
    3334     open (FILE, ">".$Path) || die ("can't open file \'$Path\': $!\n");
    3335     print FILE $Content;
    3336     close(FILE);
    3337 }
    3338 
    3339 sub readFile($)
    3340 {
    3341     my $Path = $_[0];
    3342     return "" if(not $Path or not -f $Path);
    3343     open (FILE, $Path);
    3344     my $Content = join("", <FILE>);
    3345     close(FILE);
    3346     $Content=~s/\r//g;
    3347     return $Content;
    3348 }
    3349 
    3350 sub appendFile($$)
    3351 {
    3352     my ($Path, $Content) = @_;
    3353     return if(not $Path);
    3354     if(my $Dir = get_dirname($Path)) {
    3355         mkpath($Dir);
    3356     }
    3357     open(FILE, ">>".$Path) || die ("can't open file \'$Path\': $!\n");
    3358     print FILE $Content;
    3359     close(FILE);
    3360 }
    3361 
    3362 sub get_Report_Header($)
     2192    return ($Cache{"getSignature"}{$LVer}{$Method}{$Kind} = $Signature);
     2193}
     2194
     2195sub getReportHeader($)
    33632196{
    33642197    my $Level = $_[0];
     
    33732206        $Report_Header .= "API compatibility";
    33742207    }
    3375     $Report_Header .= " report for the <span style='color:Blue;'>$TargetTitle</span> library between <span style='color:Red;'>".$Descriptor{1}{"Version"}."</span> and <span style='color:Red;'>".$Descriptor{2}{"Version"}."</span> versions";
    3376     if($ClientPath) {
    3377         $Report_Header .= " (concerning portability of the client: <span style='color:Blue;'>".get_filename($ClientPath)."</span>)";
     2208    $Report_Header .= " report for the <span style='color:Blue;'>".$In::Opt{"TargetTitle"}."</span> library between <span style='color:Red;'>".$In::Desc{1}{"Version"}."</span> and <span style='color:Red;'>".$In::Desc{2}{"Version"}."</span> versions";
     2209    if($In::Opt{"ClientPath"}) {
     2210        $Report_Header .= " (concerning portability of the client: <span style='color:Blue;'>".getFilename($In::Opt{"ClientPath"})."</span>)";
    33782211    }
    33792212    $Report_Header .= "</h1>\n";
     
    33812214}
    33822215
    3383 sub get_SourceInfo()
     2216sub getSourceInfo()
    33842217{
    33852218    my $CheckedArchives = "<a name='Checked_Archives'></a>";
    3386     if($OldStyle) {
    3387         $CheckedArchives .= "<h2>Java ARchives (".keys(%{$LibArchives{1}}).")</h2>";
     2219    if($In::Opt{"OldStyle"}) {
     2220        $CheckedArchives .= "<h2>Java Archives (".keys(%{$LibArchives{1}}).")</h2>";
    33882221    }
    33892222    else {
    3390         $CheckedArchives .= "<h2>Java ARchives <span class='gray'>&nbsp;".keys(%{$LibArchives{1}})."&nbsp;</span></h2>";
     2223        $CheckedArchives .= "<h2>Java Archives <span class='gray'>&nbsp;".keys(%{$LibArchives{1}})."&nbsp;</span></h2>";
    33912224    }
    33922225    $CheckedArchives .= "\n<hr/><div class='jar_list'>\n";
    33932226    foreach my $ArchivePath (sort {lc($a) cmp lc($b)}  keys(%{$LibArchives{1}})) {
    3394         $CheckedArchives .= get_filename($ArchivePath)."<br/>\n";
     2227        $CheckedArchives .= getFilename($ArchivePath)."<br/>\n";
    33952228    }
    33962229    $CheckedArchives .= "</div><br/>$TOP_REF<br/>\n";
     
    33982231}
    33992232
    3400 sub get_TypeProblems_Count($$)
     2233sub getTypeProblemsCount($$)
    34012234{
    34022235    my ($TargetSeverity, $Level) = @_;
     
    34082241        foreach my $Kind (sort keys(%{$TypeChanges{$Level}{$Type_Name}}))
    34092242        {
    3410             if($TypeProblems_Kind{$Level}{$Kind} ne $TargetSeverity) {
     2243            if($CompatRules{$Level}{$Kind}{"Severity"} ne $TargetSeverity) {
    34112244                next;
    34122245            }
     2246           
    34132247            foreach my $Location (sort keys(%{$TypeChanges{$Level}{$Type_Name}{$Kind}}))
    34142248            {
     
    34282262}
    34292263
    3430 sub show_number($)
     2264sub showNum($)
    34312265{
    34322266    if($_[0])
    34332267    {
    3434         my $Num = cut_off_number($_[0], 2, 0);
     2268        my $Num = cutNum($_[0], 2, 0);
    34352269        if($Num eq "0")
    34362270        {
    34372271            foreach my $P (3 .. 7)
    34382272            {
    3439                 $Num = cut_off_number($_[0], $P, 1);
     2273                $Num = cutNum($_[0], $P, 1);
    34402274                if($Num ne "0") {
    34412275                    last;
     
    34512285}
    34522286
    3453 sub cut_off_number($$$)
     2287sub cutNum($$$)
    34542288{
    34552289    my ($num, $digs_to_cut, $z) = @_;
     
    34772311}
    34782312
    3479 sub get_Summary($)
     2313sub getSummary($)
    34802314{
    34812315    my $Level = $_[0];
    34822316    my ($Added, $Removed, $M_Problems_High, $M_Problems_Medium, $M_Problems_Low,
    3483     $T_Problems_High, $T_Problems_Medium, $T_Problems_Low, $M_Other, $T_Other) = (0,0,0,0,0,0,0,0,0,0);
     2317    $T_Problems_High, $T_Problems_Medium, $T_Problems_Low, $M_Other, $T_Other) = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    34842318   
    34852319    %{$RESULT{$Level}} = (
    34862320        "Problems"=>0,
    34872321        "Warnings"=>0,
    3488         "Affected"=>0 );
     2322        "Affected"=>0);
    34892323   
    34902324    foreach my $Method (sort keys(%CompatProblems))
     
    34922326        foreach my $Kind (sort keys(%{$CompatProblems{$Method}}))
    34932327        {
    3494             if(my $Severity = $MethodProblems_Kind{$Level}{$Kind})
    3495             {
    3496                 foreach my $Location (sort keys(%{$CompatProblems{$Method}{$Kind}}))
     2328            if($CompatRules{$Level}{$Kind}{"Kind"} eq "Methods")
     2329            {
     2330                my $Severity = $CompatRules{$Level}{$Kind}{"Severity"};
     2331                foreach my $Loc (sort keys(%{$CompatProblems{$Method}{$Kind}}))
    34972332                {
    34982333                    if($Kind eq "Added_Method")
     
    35312366                            $M_Problems_Low+=1;
    35322367                        }
    3533                         if(($Severity ne "Low" or $StrictCompat)
     2368                        if(($Severity ne "Low" or $In::Opt{"StrictCompat"})
    35342369                        and $Severity ne "Safe") {
    35352370                            $TotalAffected{$Level}{$Method} = $Severity;
     
    35452380    foreach my $Method (sort keys(%CompatProblems))
    35462381    {
    3547         my @Kinds = sort keys(%{$CompatProblems{$Method}});
    3548         foreach my $Kind (@Kinds)
    3549         {
    3550             if(my $Severity = $TypeProblems_Kind{$Level}{$Kind})
    3551             {
    3552                 my @Locs = sort {length($a)<=>length($b)} sort keys(%{$CompatProblems{$Method}{$Kind}});
    3553                 foreach my $Location (@Locs)
     2382        foreach my $Kind (sort keys(%{$CompatProblems{$Method}}))
     2383        {
     2384            if($CompatRules{$Level}{$Kind}{"Kind"} eq "Types")
     2385            {
     2386                my $Severity = $CompatRules{$Level}{$Kind}{"Severity"};
     2387                if(($Severity ne "Low" or $In::Opt{"StrictCompat"})
     2388                and $Severity ne "Safe")
    35542389                {
    3555                     my $Type_Name = $CompatProblems{$Method}{$Kind}{$Location}{"Type_Name"};
    3556                     my $Target = $CompatProblems{$Method}{$Kind}{$Location}{"Target"};
     2390                    if(my $Sev = $TotalAffected{$Level}{$Method})
     2391                    {
     2392                        if($Severity_Val{$Severity}>$Severity_Val{$Sev}) {
     2393                            $TotalAffected{$Level}{$Method} = $Severity;
     2394                        }
     2395                    }
     2396                    else {
     2397                        $TotalAffected{$Level}{$Method} = $Severity;
     2398                    }
     2399                }
     2400               
     2401                my $MK = $CompatProblems{$Method}{$Kind};
     2402                my (@Locs1, @Locs2) = ();
     2403                foreach my $Loc (sort {length($a)<=>length($b)} sort keys(%{$MK}))
     2404                {
     2405                    if(index($Loc, "retval")==0 or index($Loc, "this")==0) {
     2406                        push(@Locs2, $Loc);
     2407                    }
     2408                    else {
     2409                        push(@Locs1, $Loc);
     2410                    }
     2411                }
     2412                foreach my $Loc (@Locs1, @Locs2)
     2413                {
     2414                    my $Type = $MK->{$Loc}{"Type_Name"};
     2415                    my $Target = $MK->{$Loc}{"Target"};
    35572416                   
    3558                     if(defined $MethodTypeIndex{$Method}{$Type_Name}{$Kind}{$Target})
     2417                    if(defined $MethodTypeIndex{$Method}{$Type}{$Kind}{$Target})
    35592418                    { # one location for one type and target
    35602419                        next;
    35612420                    }
    3562                     $MethodTypeIndex{$Method}{$Type_Name}{$Kind}{$Target} = 1;
    3563                     $TypeChanges{$Level}{$Type_Name}{$Kind}{$Location} = $CompatProblems{$Method}{$Kind}{$Location};
     2421                    $MethodTypeIndex{$Method}{$Type}{$Kind}{$Target} = 1;
    35642422                   
    3565                     if(($Severity ne "Low" or $StrictCompat)
    3566                     and $Severity ne "Safe")
    3567                     {
    3568                         if(my $Sev = $TotalAffected{$Level}{$Method})
    3569                         {
    3570                             if($Severity_Val{$Severity}>$Severity_Val{$Sev}) {
    3571                                 $TotalAffected{$Level}{$Method} = $Severity;
    3572                             }
    3573                         }
    3574                         else {
    3575                             $TotalAffected{$Level}{$Method} = $Severity;
    3576                         }
    3577                     }
     2423                    $TypeChanges{$Level}{$Type}{$Kind}{$Loc} = $MK->{$Loc};
     2424                    $TypeProblemsIndex{$Level}{$Type}{$Kind}{$Loc}{$Method} = 1;
    35782425                }
    35792426            }
     
    35832430    %MethodTypeIndex = (); # clear memory
    35842431   
    3585    
    3586     $T_Problems_High = get_TypeProblems_Count("High", $Level);
    3587     $T_Problems_Medium = get_TypeProblems_Count("Medium", $Level);
    3588     $T_Problems_Low = get_TypeProblems_Count("Low", $Level);
    3589     $T_Other = get_TypeProblems_Count("Safe", $Level);
     2432    $T_Problems_High = getTypeProblemsCount("High", $Level);
     2433    $T_Problems_Medium = getTypeProblemsCount("Medium", $Level);
     2434    $T_Problems_Low = getTypeProblemsCount("Low", $Level);
     2435    $T_Other = getTypeProblemsCount("Safe", $Level);
    35902436   
    35912437    my $SCount = keys(%CheckedMethods)-$Added;
     
    36052451        $RESULT{$Level}{"Affected"} = 0;
    36062452    }
    3607     $RESULT{$Level}{"Affected"} = show_number($RESULT{$Level}{"Affected"});
     2453    $RESULT{$Level}{"Affected"} = showNum($RESULT{$Level}{"Affected"});
    36082454    if($RESULT{$Level}{"Affected"}>=100) {
    36092455        $RESULT{$Level}{"Affected"} = 100;
     
    36152461    $TestInfo .= "<h2>Test Info</h2><hr/>\n";
    36162462    $TestInfo .= "<table class='summary'>\n";
    3617     $TestInfo .= "<tr><th>Library Name</th><td>$TargetTitle</td></tr>\n";
    3618     $TestInfo .= "<tr><th>Version #1</th><td>".$Descriptor{1}{"Version"}."</td></tr>\n";
    3619     $TestInfo .= "<tr><th>Version #2</th><td>".$Descriptor{2}{"Version"}."</td></tr>\n";
    3620    
    3621     if($JoinReport)
     2463    $TestInfo .= "<tr><th>Library Name</th><td>".$In::Opt{"TargetTitle"}."</td></tr>\n";
     2464    $TestInfo .= "<tr><th>Version #1</th><td>".$In::Desc{1}{"Version"}."</td></tr>\n";
     2465    $TestInfo .= "<tr><th>Version #2</th><td>".$In::Desc{2}{"Version"}."</td></tr>\n";
     2466   
     2467    if($In::Opt{"JoinReport"})
    36222468    {
    36232469        if($Level eq "Binary") {
     
    36312477   
    36322478    # test results
    3633     $TestResults .= "<h2>Test Results</h2><hr/>";
    3634     $TestResults .= "<table class='summary'>";
     2479    $TestResults .= "<h2>Test Results</h2><hr/>\n";
     2480    $TestResults .= "<table class='summary'>\n";
    36352481   
    36362482    my $Checked_Archives_Link = "0";
     
    36412487   
    36422488    $RESULT{$Level}{"Problems"} += $Removed+$M_Problems_High+$T_Problems_High+$T_Problems_Medium+$M_Problems_Medium;
    3643     if($StrictCompat) {
     2489    if($In::Opt{"StrictCompat"}) {
    36442490        $RESULT{$Level}{"Problems"}+=$T_Problems_Low+$M_Problems_Low;
    36452491    }
     
    36522498    $TestResults .= "<tr><th>Compatibility</th>\n";
    36532499   
    3654     my $BC_Rate = show_number(100 - $RESULT{$Level}{"Affected"});
     2500    my $BC_Rate = showNum(100 - $RESULT{$Level}{"Affected"});
    36552501   
    36562502    if($RESULT{$Level}{"Problems"})
     
    36772523   
    36782524    # Problem Summary
    3679     $Problem_Summary .= "<h2>Problem Summary</h2><hr/>";
    3680     $Problem_Summary .= "<table class='summary'>";
    3681     $Problem_Summary .= "<tr><th></th><th style='text-align:center;'>Severity</th><th style='text-align:center;'>Count</th></tr>";
     2525    $Problem_Summary .= "<h2>Problem Summary</h2><hr/>\n";
     2526    $Problem_Summary .= "<table class='summary'>\n";
     2527    $Problem_Summary .= "<tr><th></th><th style='text-align:center;'>Severity</th><th style='text-align:center;'>Count</th></tr>\n";
    36822528   
    36832529    my $Added_Link = "0";
    36842530    if($Added>0)
    36852531    {
    3686         if($ShortMode) {
     2532        if($In::Opt{"ShortMode"}) {
    36872533            $Added_Link = $Added;
    36882534        }
    36892535        else
    36902536        {
    3691             if($JoinReport) {
     2537            if($In::Opt{"JoinReport"}) {
    36922538                $Added_Link = "<a href='#".$Level."_Added' style='color:Blue;'>$Added</a>";
    36932539            }
     
    36982544    }
    36992545    $META_DATA .= "added:$Added;";
    3700     $Problem_Summary .= "<tr><th>Added Methods</th><td>-</td><td".getStyle("M", "Added", $Added).">$Added_Link</td></tr>";
     2546    $Problem_Summary .= "<tr><th>Added Methods</th><td>-</td><td".getStyle("M", "Added", $Added).">$Added_Link</td></tr>\n";
    37012547   
    37022548    my $Removed_Link = "0";
    37032549    if($Removed>0)
    37042550    {
    3705         if($ShortMode) {
     2551        if($In::Opt{"ShortMode"}) {
    37062552            $Removed_Link = $Removed;
    37072553        }
    37082554        else
    37092555        {
    3710             if($JoinReport) {
     2556            if($In::Opt{"JoinReport"}) {
    37112557                $Removed_Link = "<a href='#".$Level."_Removed' style='color:Blue;'>$Removed</a>"
    37122558            }
     
    37182564    $META_DATA .= "removed:$Removed;";
    37192565    $Problem_Summary .= "<tr><th>Removed Methods</th>";
    3720     $Problem_Summary .= "<td>High</td><td".getStyle("M", "Removed", $Removed).">$Removed_Link</td></tr>";
     2566    $Problem_Summary .= "<td>High</td><td".getStyle("M", "Removed", $Removed).">$Removed_Link</td></tr>\n";
    37212567   
    37222568    my $TH_Link = "0";
    3723     $TH_Link = "<a href='#".get_Anchor("Type", $Level, "High")."' style='color:Blue;'>$T_Problems_High</a>" if($T_Problems_High>0);
     2569    $TH_Link = "<a href='#".getAnchor("Type", $Level, "High")."' style='color:Blue;'>$T_Problems_High</a>" if($T_Problems_High>0);
    37242570    $META_DATA .= "type_problems_high:$T_Problems_High;";
    37252571    $Problem_Summary .= "<tr><th rowspan='3'>Problems with<br/>Data Types</th>";
    3726     $Problem_Summary .= "<td>High</td><td".getStyle("T", "High", $T_Problems_High).">$TH_Link</td></tr>";
     2572    $Problem_Summary .= "<td>High</td><td".getStyle("T", "High", $T_Problems_High).">$TH_Link</td></tr>\n";
    37272573   
    37282574    my $TM_Link = "0";
    3729     $TM_Link = "<a href='#".get_Anchor("Type", $Level, "Medium")."' style='color:Blue;'>$T_Problems_Medium</a>" if($T_Problems_Medium>0);
     2575    $TM_Link = "<a href='#".getAnchor("Type", $Level, "Medium")."' style='color:Blue;'>$T_Problems_Medium</a>" if($T_Problems_Medium>0);
    37302576    $META_DATA .= "type_problems_medium:$T_Problems_Medium;";
    3731     $Problem_Summary .= "<tr><td>Medium</td><td".getStyle("T", "Medium", $T_Problems_Medium).">$TM_Link</td></tr>";
     2577    $Problem_Summary .= "<tr><td>Medium</td><td".getStyle("T", "Medium", $T_Problems_Medium).">$TM_Link</td></tr>\n";
    37322578   
    37332579    my $TL_Link = "0";
    3734     $TL_Link = "<a href='#".get_Anchor("Type", $Level, "Low")."' style='color:Blue;'>$T_Problems_Low</a>" if($T_Problems_Low>0);
     2580    $TL_Link = "<a href='#".getAnchor("Type", $Level, "Low")."' style='color:Blue;'>$T_Problems_Low</a>" if($T_Problems_Low>0);
    37352581    $META_DATA .= "type_problems_low:$T_Problems_Low;";
    3736     $Problem_Summary .= "<tr><td>Low</td><td".getStyle("T", "Low", $T_Problems_Low).">$TL_Link</td></tr>";
     2582    $Problem_Summary .= "<tr><td>Low</td><td".getStyle("T", "Low", $T_Problems_Low).">$TL_Link</td></tr>\n";
    37372583   
    37382584    my $MH_Link = "0";
    3739     $MH_Link = "<a href='#".get_Anchor("Method", $Level, "High")."' style='color:Blue;'>$M_Problems_High</a>" if($M_Problems_High>0);
     2585    $MH_Link = "<a href='#".getAnchor("Method", $Level, "High")."' style='color:Blue;'>$M_Problems_High</a>" if($M_Problems_High>0);
    37402586    $META_DATA .= "method_problems_high:$M_Problems_High;";
    37412587    $Problem_Summary .= "<tr><th rowspan='3'>Problems with<br/>Methods</th>";
    3742     $Problem_Summary .= "<td>High</td><td".getStyle("M", "High", $M_Problems_High).">$MH_Link</td></tr>";
     2588    $Problem_Summary .= "<td>High</td><td".getStyle("M", "High", $M_Problems_High).">$MH_Link</td></tr>\n";
    37432589   
    37442590    my $MM_Link = "0";
    3745     $MM_Link = "<a href='#".get_Anchor("Method", $Level, "Medium")."' style='color:Blue;'>$M_Problems_Medium</a>" if($M_Problems_Medium>0);
     2591    $MM_Link = "<a href='#".getAnchor("Method", $Level, "Medium")."' style='color:Blue;'>$M_Problems_Medium</a>" if($M_Problems_Medium>0);
    37462592    $META_DATA .= "method_problems_medium:$M_Problems_Medium;";
    3747     $Problem_Summary .= "<tr><td>Medium</td><td".getStyle("M", "Medium", $M_Problems_Medium).">$MM_Link</td></tr>";
     2593    $Problem_Summary .= "<tr><td>Medium</td><td".getStyle("M", "Medium", $M_Problems_Medium).">$MM_Link</td></tr>\n";
    37482594   
    37492595    my $ML_Link = "0";
    3750     $ML_Link = "<a href='#".get_Anchor("Method", $Level, "Low")."' style='color:Blue;'>$M_Problems_Low</a>" if($M_Problems_Low>0);
     2596    $ML_Link = "<a href='#".getAnchor("Method", $Level, "Low")."' style='color:Blue;'>$M_Problems_Low</a>" if($M_Problems_Low>0);
    37512597    $META_DATA .= "method_problems_low:$M_Problems_Low;";
    3752     $Problem_Summary .= "<tr><td>Low</td><td".getStyle("M", "Low", $M_Problems_Low).">$ML_Link</td></tr>";
     2598    $Problem_Summary .= "<tr><td>Low</td><td".getStyle("M", "Low", $M_Problems_Low).">$ML_Link</td></tr>\n";
    37532599   
    37542600    # Safe Changes
    37552601    if($T_Other)
    37562602    {
    3757         my $TS_Link = "<a href='#".get_Anchor("Type", $Level, "Safe")."' style='color:Blue;'>$T_Other</a>";
     2603        my $TS_Link = "<a href='#".getAnchor("Type", $Level, "Safe")."' style='color:Blue;'>$T_Other</a>";
    37582604        $Problem_Summary .= "<tr><th>Other Changes<br/>in Data Types</th><td>-</td><td".getStyle("T", "Safe", $T_Other).">$TS_Link</td></tr>\n";
    37592605    }
     
    37612607    if($M_Other)
    37622608    {
    3763         my $MS_Link = "<a href='#".get_Anchor("Method", $Level, "Safe")."' style='color:Blue;'>$M_Other</a>";
     2609        my $MS_Link = "<a href='#".getAnchor("Method", $Level, "Safe")."' style='color:Blue;'>$M_Other</a>";
    37642610        $Problem_Summary .= "<tr><th>Other Changes<br/>in Methods</th><td>-</td><td".getStyle("M", "Safe", $M_Other).">$MS_Link</td></tr>\n";
    37652611    }
     
    37902636}
    37912637
    3792 sub get_Anchor($$$)
     2638sub getAnchor($$$)
    37932639{
    37942640    my ($Kind, $Level, $Severity) = @_;
    3795     if($JoinReport)
     2641    if($In::Opt{"JoinReport"})
    37962642    {
    37972643        if($Severity eq "Safe") {
     
    38132659}
    38142660
    3815 sub get_Report_Added($)
    3816 {
    3817     if($ShortMode) {
     2661sub getReportAdded($)
     2662{
     2663    if($In::Opt{"ShortMode"}) {
    38182664        return "";
    38192665    }
     
    38282674            {
    38292675                my $ArchiveName = $MethodInfo{2}{$Method}{"Archive"};
    3830                 my $ClassName = get_ShortName($MethodInfo{2}{$Method}{"Class"}, 2);
     2676                my $ClassName = getShortName($MethodInfo{2}{$Method}{"Class"}, 2);
    38312677                if($Level eq "Source")
    38322678                {
     
    38542700            foreach my $NameSpace (sort keys(%NameSpace_Method))
    38552701            {
    3856                 $ADDED_METHODS .= "<span class='jar'>$ArchiveName</span>, <span class='cname'>".htmlSpecChars($ShowClass).".class</span><br/>\n";
     2702                $ADDED_METHODS .= "<span class='jar'>$ArchiveName</span>, <span class='cname'>".specChars($ShowClass).".class</span><br/>\n";
    38572703               
    38582704                if($NameSpace) {
     
    38602706                }
    38612707               
    3862                 if($Compact) {
     2708                if($In::Opt{"Compact"}) {
    38632709                    $ADDED_METHODS .= "<div class='symbols'>";
    38642710                }
     
    38712717                    my $Signature = undef;
    38722718                   
    3873                     if($Compact) {
    3874                         $Signature = get_Signature($Method, 2, "Full|HTML|Simple");
     2719                    if($In::Opt{"Compact"}) {
     2720                        $Signature = getSignature($Method, 2, "Full|HTML|Simple");
    38752721                    }
    38762722                    else {
    3877                         $Signature = highLight_Signature_Italic_Color($Method, 2);
     2723                        $Signature = highLight_ItalicColor($Method, 2);
    38782724                    }
    38792725                   
     
    38822728                    }
    38832729                   
    3884                     if($Compact) {
     2730                    if($In::Opt{"Compact"}) {
    38852731                        $ADDED_METHODS .= "&nbsp;".$Signature."<br/>\n";
    38862732                    }
    38872733                    else {
    3888                         $ADDED_METHODS .= insertIDs($ContentSpanStart.$Signature.$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mngl'>[mangled: <b>".htmlSpecChars($Method)."</b>]</span><br/><br/>".$ContentDivEnd."\n");
     2734                        $ADDED_METHODS .= insertIDs($ContentSpanStart.$Signature.$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mngl'>".specChars($Method)."</span><br/><br/>".$ContentDivEnd."\n");
    38892735                    }
    38902736                }
    38912737               
    3892                 if($Compact) {
     2738                if($In::Opt{"Compact"}) {
    38932739                    $ADDED_METHODS .= "</div>";
    38942740                }
     
    39022748    {
    39032749        my $Anchor = "<a name='Added'></a>";
    3904         if($JoinReport) {
     2750        if($In::Opt{"JoinReport"}) {
    39052751            $Anchor = "<a name='".$Level."_Added'></a>";
    39062752        }
    3907         if($OldStyle) {
     2753        if($In::Opt{"OldStyle"}) {
    39082754            $ADDED_METHODS = "<h2>Added Methods ($Added_Number)</h2><hr/>\n".$ADDED_METHODS;
    39092755        }
     
    39162762}
    39172763
    3918 sub get_Report_Removed($)
    3919 {
    3920     if($ShortMode) {
     2764sub getReportRemoved($)
     2765{
     2766    if($In::Opt{"ShortMode"}) {
    39212767        return "";
    39222768    }
     
    39372783                }
    39382784                my $ArchiveName = $MethodInfo{1}{$Method}{"Archive"};
    3939                 my $ClassName = get_ShortName($MethodInfo{1}{$Method}{"Class"}, 1);
     2785                my $ClassName = getShortName($MethodInfo{1}{$Method}{"Class"}, 1);
    39402786                $MethodRemovedFromArchiveClass{$ArchiveName}{$ClassName}{$Method} = 1;
    39412787            }
     
    39582804            foreach my $NameSpace (sort keys(%NameSpace_Method))
    39592805            {
    3960                 $REMOVED_METHODS .= "<span class='jar'>$ArchiveName</span>, <span class='cname'>".htmlSpecChars($ShowClass).".class</span><br/>\n";
     2806                $REMOVED_METHODS .= "<span class='jar'>$ArchiveName</span>, <span class='cname'>".specChars($ShowClass).".class</span><br/>\n";
    39612807               
    39622808                if($NameSpace) {
     
    39642810                }
    39652811               
    3966                 if($Compact) {
     2812                if($In::Opt{"Compact"}) {
    39672813                    $REMOVED_METHODS .= "<div class='symbols'>";
    39682814                }
     
    39752821                    my $Signature = undef;
    39762822                   
    3977                     if($Compact) {
    3978                         $Signature = get_Signature($Method, 1, "Full|HTML|Simple");
     2823                    if($In::Opt{"Compact"}) {
     2824                        $Signature = getSignature($Method, 1, "Full|HTML|Simple");
    39792825                    }
    39802826                    else {
    3981                         $Signature = highLight_Signature_Italic_Color($Method, 1);
     2827                        $Signature = highLight_ItalicColor($Method, 1);
    39822828                    }
    39832829                   
     
    39862832                    }
    39872833                   
    3988                     if($Compact) {
     2834                    if($In::Opt{"Compact"}) {
    39892835                        $REMOVED_METHODS .= "&nbsp;".$Signature."<br/>\n";
    39902836                    }
    39912837                    else {
    3992                         $REMOVED_METHODS .= insertIDs($ContentSpanStart.$Signature.$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mngl'>[mangled: <b>".htmlSpecChars($Method)."</b>]</span><br/><br/>".$ContentDivEnd."\n");
     2838                        $REMOVED_METHODS .= insertIDs($ContentSpanStart.$Signature.$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mngl'>".specChars($Method)."</span><br/><br/>".$ContentDivEnd."\n");
    39932839                    }
    39942840                }
    39952841               
    3996                 if($Compact) {
     2842                if($In::Opt{"Compact"}) {
    39972843                    $REMOVED_METHODS .= "</div>";
    39982844                }
     
    40052851    {
    40062852        my $Anchor = "<a name='Removed'></a><a name='Withdrawn'></a>";
    4007         if($JoinReport) {
     2853        if($In::Opt{"JoinReport"}) {
    40082854            $Anchor = "<a name='".$Level."_Removed'></a><a name='".$Level."_Withdrawn'></a>";
    40092855        }
    4010         if($OldStyle) {
     2856        if($In::Opt{"OldStyle"}) {
    40112857            $REMOVED_METHODS = "<h2>Removed Methods ($Removed_Number)</h2><hr/>\n".$REMOVED_METHODS;
    40122858        }
     
    40192865}
    40202866
    4021 sub get_Report_MethodProblems($$)
     2867sub readRules($)
     2868{
     2869    my $Kind = $_[0];
     2870    if(not -f $RULES_PATH{$Kind}) {
     2871        exitStatus("Module_Error", "can't access \'".$RULES_PATH{$Kind}."\'");
     2872    }
     2873    my $Content = readFile($RULES_PATH{$Kind});
     2874    while(my $Rule = parseTag(\$Content, "rule"))
     2875    {
     2876        my $RId = parseTag(\$Rule, "id");
     2877        my @Properties = ("Severity", "Change", "Effect", "Overcome", "Kind");
     2878        foreach my $Prop (@Properties) {
     2879            if(my $Value = parseTag(\$Rule, lc($Prop)))
     2880            {
     2881                $Value=~s/\n[ ]*//;
     2882                $CompatRules{$Kind}{$RId}{$Prop} = $Value;
     2883            }
     2884        }
     2885        if($CompatRules{$Kind}{$RId}{"Kind"}=~/\A(Methods|Parameters)\Z/) {
     2886            $CompatRules{$Kind}{$RId}{"Kind"} = "Methods";
     2887        }
     2888        else { # Types, Fields
     2889            $CompatRules{$Kind}{$RId}{"Kind"} = "Types";
     2890        }
     2891    }
     2892}
     2893
     2894sub addMarkup($)
     2895{
     2896    my $Content = $_[0];
     2897   
     2898    # auto-markup
     2899    $Content=~s/\n[ ]*//; # spaces
     2900    $Content=~s!([2-9]\))!<br/>$1!g; # 1), 2), ...
     2901    if($Content=~/\ANOTE:/)
     2902    { # notes
     2903        $Content=~s!(NOTE):!<b>$1</b>:!g;
     2904    }
     2905    else {
     2906        $Content=~s!(NOTE):!<br/><br/><b>$1</b>:!g;
     2907    }
     2908   
     2909    my @Keywords = (
     2910        "static",
     2911        "abstract",
     2912        "default",
     2913        "final",
     2914        "synchronized"
     2915    );
     2916   
     2917    my $MKeys = join("|", @Keywords);
     2918    foreach (@Keywords) {
     2919        $MKeys .= "|non-".$_;
     2920    }
     2921   
     2922    $Content=~s!(became\s*)($MKeys)([^\w-]|\Z)!$1<b>$2</b>$3!ig; # intrinsic types, modifiers
     2923   
     2924    # Markdown
     2925    $Content=~s!\*\*([\w\-\@]+)\*\*!<b>$1</b>!ig;
     2926    $Content=~s!\*([\w\-]+)\*!<i>$1</i>!ig;
     2927   
     2928    return $Content;
     2929}
     2930
     2931sub applyMacroses($$$$$)
     2932{
     2933    my ($Level, $Kind, $Content, $Problem, $AddAttr) = @_;
     2934   
     2935    $Content = addMarkup($Content);
     2936   
     2937    # macros
     2938    foreach my $Attr (sort {$b cmp $a} (keys(%{$Problem}), keys(%{$AddAttr})))
     2939    {
     2940        my $Macro = "\@".lc($Attr);
     2941        my $Value = undef;
     2942       
     2943        if(defined $Problem->{$Attr}) {
     2944            $Value = $Problem->{$Attr};
     2945        }
     2946        else {
     2947            $Value = $AddAttr->{$Attr};
     2948        }
     2949       
     2950        if(not defined $Value
     2951        or $Value eq "") {
     2952            next;
     2953        }
     2954       
     2955        if(index($Content, $Macro)==-1) {
     2956            next;
     2957        }
     2958       
     2959        if($Attr eq "Param_Pos") {
     2960            $Value = showPos($Value);
     2961        }
     2962       
     2963        if($Attr eq "Invoked") {
     2964            $Value = blackName(specChars($Value));
     2965        }
     2966        elsif($Value=~/\s/) {
     2967            $Value = "<span class='value'>".specChars($Value)."</span>";
     2968        }
     2969        else
     2970        {
     2971            my $Fmt = "Class|HTML|Desc";
     2972           
     2973            if($Attr ne "Invoked_By")
     2974            {
     2975                if($Attr eq "Method_Short"
     2976                or $Kind!~/Overridden|Moved_Up/) {
     2977                    $Fmt = "HTML|Desc";
     2978                }
     2979            }
     2980           
     2981            if(defined $MethodInfo{1}{$Value}
     2982            and defined $MethodInfo{1}{$Value}{"ShortName"}) {
     2983                $Value = blackName(getSignature($Value, 1, $Fmt));
     2984            }
     2985            elsif(defined $MethodInfo{2}{$Value}
     2986            and defined $MethodInfo{2}{$Value}{"ShortName"}) {
     2987                $Value = blackName(getSignature($Value, 2, $Fmt));
     2988            }
     2989            else
     2990            {
     2991                $Value = specChars($Value);
     2992                if($Attr ne "Type_Type") {
     2993                    $Value = "<b>".$Value."</b>";
     2994                }
     2995            }
     2996        }
     2997        $Content=~s/\Q$Macro\E/$Value/g;
     2998    }
     2999   
     3000    if($Content=~/(\A|[^\@\w])(\@\w+)/)
     3001    {
     3002        if(not $IncompleteRules{$Level}{$Kind})
     3003        { # only one warning
     3004            printMsg("WARNING", "incomplete $2 in the rule \"$Kind\" (\"$Level\")");
     3005            $IncompleteRules{$Level}{$Kind} = 1;
     3006        }
     3007    }
     3008   
     3009    return $Content;
     3010}
     3011
     3012sub getReportMethodProblems($$)
    40223013{
    40233014    my ($TargetSeverity, $Level) = @_;
     
    40283019    {
    40293020        my $ArchiveName = $MethodInfo{1}{$Method}{"Archive"};
    4030         my $ClassName = get_ShortName($MethodInfo{1}{$Method}{"Class"}, 1);
     3021        my $ClassName = getShortName($MethodInfo{1}{$Method}{"Class"}, 1);
    40313022       
    40323023        foreach my $Kind (sort keys(%{$CompatProblems{$Method}}))
    40333024        {
    4034             if($Kind eq "Added_Method"
    4035             or $Kind eq "Removed_Method") {
    4036                 next;
    4037             }
    4038            
    4039             if(my $Severity = $MethodProblems_Kind{$Level}{$Kind})
    4040             {
    4041                 if($Severity ne $TargetSeverity) {
     3025            if($CompatRules{$Level}{$Kind}{"Kind"} eq "Methods")
     3026            {
     3027                if($Kind eq "Added_Method"
     3028                or $Kind eq "Removed_Method") {
    40423029                    next;
    40433030                }
    40443031               
    4045                 $MethodChanges{$Method}{$Kind} = $CompatProblems{$Method}{$Kind};
    4046                 $ReportMap{$ArchiveName}{$ClassName}{$Method} = 1;
     3032                if(my $Severity = $CompatRules{$Level}{$Kind}{"Severity"})
     3033                {
     3034                    if($Severity ne $TargetSeverity) {
     3035                        next;
     3036                    }
     3037                   
     3038                    $MethodChanges{$Method}{$Kind} = $CompatProblems{$Method}{$Kind};
     3039                    $ReportMap{$ArchiveName}{$ClassName}{$Method} = 1;
     3040                }
    40473041            }
    40483042        }
     
    40633057            foreach my $NameSpace (sort keys(%NameSpace_Method))
    40643058            {
    4065                 $METHOD_PROBLEMS .= "<span class='jar'>$ArchiveName</span>, <span class='cname'>".htmlSpecChars($ShowClass).".class</span><br/>\n";
     3059                $METHOD_PROBLEMS .= "<span class='jar'>$ArchiveName</span>, <span class='cname'>".specChars($ShowClass).".class</span><br/>\n";
    40663060                if($NameSpace) {
    40673061                    $METHOD_PROBLEMS .= "<span class='pkg_t'>package</span> <span class='pkg'>$NameSpace</span><br/>\n";
     
    40713065                foreach my $Method (@SortedMethods)
    40723066                {
    4073                     my $ShortSignature = get_Signature($Method, 1, "Short");
    4074                     my $ClassName_Full = get_TypeName($MethodInfo{1}{$Method}{"Class"}, 1);
     3067                    my %AddAttr = ();
     3068                   
     3069                    $AddAttr{"Method_Short"} = $Method;
     3070                    $AddAttr{"Class"} = getTypeName($MethodInfo{1}{$Method}{"Class"}, 1);
     3071                   
    40753072                    my $METHOD_REPORT = "";
    40763073                    my $ProblemNum = 1;
    40773074                    foreach my $Kind (sort keys(%{$MethodChanges{$Method}}))
    40783075                    {
    4079                         foreach my $Location (sort keys(%{$MethodChanges{$Method}{$Kind}}))
     3076                        foreach my $Loc (sort keys(%{$MethodChanges{$Method}{$Kind}}))
    40803077                        {
    4081                             my %Problems = %{$MethodChanges{$Method}{$Kind}{$Location}};
     3078                            my $ProblemAttr = $MethodChanges{$Method}{$Kind}{$Loc};
    40823079                           
    4083                             my $Target = $Problems{"Target"};
    4084                            
    4085                             my ($Change, $Effect) = ("", "");
    4086                             my $Old_Value = htmlSpecChars($Problems{"Old_Value"});
    4087                             my $New_Value = htmlSpecChars($Problems{"New_Value"});
    4088                            
    4089                             if($Kind eq "Method_Became_Static")
     3080                            if(my $Change = applyMacroses($Level, $Kind, $CompatRules{$Level}{$Kind}{"Change"}, $ProblemAttr, \%AddAttr))
    40903081                            {
    4091                                 $Change = "Method became <b>static</b>.\n";
    4092                                 $Effect = "A client program may be interrupted by <b>NoSuchMethodError</b> exception.";
    4093                             }
    4094                             elsif($Kind eq "Method_Became_NonStatic")
    4095                             {
    4096                                 $Change = "Method became <b>non-static</b>.\n";
    4097                                 if($Level eq "Binary") {
    4098                                     $Effect = "A client program may be interrupted by <b>NoSuchMethodError</b> exception.";
    4099                                 }
    4100                                 else {
    4101                                     $Effect = "Recompilation of a client program may be terminated with the message: non-static method ".htmlSpecChars($ShortSignature)." cannot be referenced from a static context.";
    4102                                 }
    4103                             }
    4104                             elsif($Kind eq "Changed_Method_Return_From_Void")
    4105                             {
    4106                                 $Change = "Return value type has been changed from <b>void</b> to <b>".htmlSpecChars($New_Value)."</b>.\n";
    4107                                 $Effect = "This method has been removed because the return type is part of the method signature.";
    4108                             }
    4109                             elsif($Kind eq "Static_Method_Became_Final")
    4110                             {# Source Only
    4111                                 $Change = "Method became <b>final</b>.\n";
    4112                                 $Effect = "Recompilation of a client program may be terminated with the message: ".htmlSpecChars($ShortSignature)." in client class C cannot override ".htmlSpecChars($ShortSignature)." in ".htmlSpecChars($ClassName_Full)."; overridden method is final.";
    4113                             }
    4114                             elsif($Kind eq "NonStatic_Method_Became_Final")
    4115                             {
    4116                                 $Change = "Method became <b>final</b>.\n";
    4117                                 if($Level eq "Binary") {
    4118                                     $Effect = "A client program trying to reimplement this method may be interrupted by <b>VerifyError</b> exception.";
    4119                                 }
    4120                                 else {
    4121                                     $Effect = "Recompilation of a client program may be terminated with the message: ".htmlSpecChars($ShortSignature)." in client class C cannot override ".htmlSpecChars($ShortSignature)." in ".htmlSpecChars($ClassName_Full)."; overridden method is final.";
    4122                                 }
    4123                             }
    4124                             elsif($Kind eq "Method_Became_Abstract")
    4125                             {
    4126                                 $Change = "Method became <b>abstract</b>.\n";
    4127                                 if($Level eq "Binary") {
    4128                                     $Effect = "A client program trying to create an instance of the method's class may be interrupted by <b>InstantiationError</b> exception.";
    4129                                 }
    4130                                 else {
    4131                                     $Effect = "Recompilation of a client program may be terminated with the message: A client class C is not abstract and does not override abstract method ".htmlSpecChars($ShortSignature)." in ".htmlSpecChars($ClassName_Full).".";
    4132                                 }
    4133                             }
    4134                             elsif($Kind eq "Method_Became_NonAbstract")
    4135                             {
    4136                                 $Change = "Method became <b>non-abstract</b>.\n";
    4137                                 if($Level eq "Binary") {
    4138                                     $Effect = "A client program may change behavior.";
    4139                                 }
    4140                                 else {
    4141                                     $Effect = "No effect.";
    4142                                 }
    4143                             }
    4144                             elsif($Kind eq "Method_Became_Default")
    4145                             {
    4146                                 $Change = "Method became <b>default</b>.\n";
    4147                                 if($Level eq "Binary") {
    4148                                     $Effect = "No effect.";
    4149                                 }
    4150                                 else {
    4151                                     $Effect = "No effect.";
    4152                                 }
    4153                             }
    4154                             elsif($Kind eq "Method_Became_NonDefault")
    4155                             {
    4156                                 $Change = "Method became <b>non-default</b>.\n";
    4157                                 if($Level eq "Binary") {
    4158                                     $Effect = "A client program trying to create an instance of a class may be interrupted by <b>AbstractMethodError</b> exception.";
    4159                                 }
    4160                                 else {
    4161                                     $Effect = "Recompilation of a client program may be terminated with the message: A client class C is not abstract and does not override abstract method ".htmlSpecChars($ShortSignature)." in ".htmlSpecChars($ClassName_Full).".";
    4162                                 }
    4163                             }
    4164                             elsif($Kind eq "Method_Became_Synchronized")
    4165                             {
    4166                                 $Change = "Method became <b>synchronized</b>.\n";
    4167                                 $Effect = "A multi-threaded client program may change behavior.";
    4168                             }
    4169                             elsif($Kind eq "Method_Became_NonSynchronized")
    4170                             {
    4171                                 $Change = "Method became <b>non-synchronized</b>.\n";
    4172                                 $Effect = "A multi-threaded client program may change behavior.";
    4173                             }
    4174                             elsif($Kind eq "Changed_Method_Access")
    4175                             {
    4176                                 $Change = "Access level has been changed from <span class='nowrap'><b>".htmlSpecChars($Old_Value)."</b></span> to <span class='nowrap'><b>".htmlSpecChars($New_Value)."</b></span>.";
    4177                                 if($Level eq "Binary") {
    4178                                     $Effect = "A client program may be interrupted by <b>IllegalAccessError</b> exception.";
    4179                                 }
    4180                                 else {
    4181                                     $Effect = "Recompilation of a client program may be terminated with the message: ".htmlSpecChars($ShortSignature)." has $New_Value access in ".htmlSpecChars($ClassName_Full).".";
    4182                                 }
    4183                             }
    4184                             elsif($Kind eq "Abstract_Method_Added_Checked_Exception")
    4185                             {# Source Only
    4186                                 $Change = "Added <b>".htmlSpecChars($Target)."</b> exception thrown.\n";
    4187                                 $Effect = "Recompilation of a client program may be terminated with the message: unreported exception ".htmlSpecChars($Target)." must be caught or declared to be thrown.";
    4188                             }
    4189                             elsif($Kind eq "NonAbstract_Method_Added_Checked_Exception")
    4190                             {
    4191                                 $Change = "Added <b>".htmlSpecChars($Target)."</b> exception thrown.\n";
    4192                                 if($Level eq "Binary") {
    4193                                     $Effect = "A client program may be interrupted by added exception.";
    4194                                 }
    4195                                 else {
    4196                                     $Effect = "Recompilation of a client program may be terminated with the message: unreported exception ".htmlSpecChars($Target)." must be caught or declared to be thrown.";
    4197                                 }
    4198                             }
    4199                             elsif($Kind eq "Abstract_Method_Removed_Checked_Exception")
    4200                             {# Source Only
    4201                                 $Change = "Removed <b>".htmlSpecChars($Target)."</b> exception thrown.\n";
    4202                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot override ".htmlSpecChars($ShortSignature)." in ".htmlSpecChars($ClassName_Full)."; overridden method does not throw ".htmlSpecChars($Target).".";
    4203                             }
    4204                             elsif($Kind eq "NonAbstract_Method_Removed_Checked_Exception")
    4205                             {
    4206                                 $Change = "Removed <b>".htmlSpecChars($Target)."</b> exception thrown.\n";
    4207                                 if($Level eq "Binary") {
    4208                                     $Effect = "A client program may change behavior because the removed exception will not be thrown any more and client will not catch and handle it.";
    4209                                 }
    4210                                 else {
    4211                                     $Effect = "Recompilation of a client program may be terminated with the message: cannot override ".htmlSpecChars($ShortSignature)." in ".htmlSpecChars($ClassName_Full)."; overridden method does not throw ".htmlSpecChars($Target).".";
    4212                                 }
    4213                             }
    4214                             elsif($Kind eq "Added_Unchecked_Exception")
    4215                             {# Binary Only
    4216                                 $Change = "Added <b>".htmlSpecChars($Target)."</b> exception thrown.\n";
    4217                                 $Effect = "A client program may be interrupted by added exception.";
    4218                             }
    4219                             elsif($Kind eq "Removed_Unchecked_Exception")
    4220                             {# Binary Only
    4221                                 $Change = "Removed <b>".htmlSpecChars($Target)."</b> exception thrown.\n";
    4222                                 $Effect = "A client program may change behavior because the removed exception will not be thrown any more and client will not catch and handle it.";
    4223                             }
    4224                             if($Change)
    4225                             {
    4226                                 $METHOD_REPORT .= "<tr><th>$ProblemNum</th><td>".$Change."</td><td>".$Effect."</td></tr>\n";
     3082                                my $Effect = applyMacroses($Level, $Kind, $CompatRules{$Level}{$Kind}{"Effect"}, $ProblemAttr, \%AddAttr);
     3083                                $METHOD_REPORT .= "<tr>\n<th>$ProblemNum</th>\n<td>".$Change."</td>\n<td>".$Effect."</td>\n</tr>\n";
    42273084                                $ProblemNum += 1;
    42283085                                $ProblemsNum += 1;
     
    42333090                    if($METHOD_REPORT)
    42343091                    {
    4235                         my $ShowMethod = highLight_Signature_Italic_Color($Method, 1);
     3092                        my $ShowMethod = highLight_ItalicColor($Method, 1);
    42363093                        if($NameSpace)
    42373094                        {
    4238                             $METHOD_REPORT = cut_Namespace($METHOD_REPORT, $NameSpace);
    4239                             $ShowMethod = cut_Namespace($ShowMethod, $NameSpace);
     3095                            $METHOD_REPORT = cutNs($METHOD_REPORT, $NameSpace);
     3096                            $ShowMethod = cutNs($ShowMethod, $NameSpace);
    42403097                        }
    42413098                       
    42423099                        $METHOD_PROBLEMS .= $ContentSpanStart."<span class='ext'>[+]</span> ".$ShowMethod;
    4243                         if($OldStyle) {
     3100                        if($In::Opt{"OldStyle"}) {
    42443101                            $METHOD_PROBLEMS .= " ($ProblemNum)";
    42453102                        }
     
    42503107                        $METHOD_PROBLEMS .= $ContentDivStart;
    42513108                       
    4252                         if(not $Compact) {
    4253                             $METHOD_PROBLEMS .= "<span class='mngl'>&#160;&#160;&#160;[mangled: <b>".htmlSpecChars($Method)."</b>]</span><br/>\n";
     3109                        if(not $In::Opt{"Compact"}) {
     3110                            $METHOD_PROBLEMS .= "<span class='mngl pleft'>".specChars($Method)."</span><br/>\n";
    42543111                        }
    42553112                       
     
    42723129            $Title = "Other Changes in Methods";
    42733130        }
    4274         if($OldStyle) {
     3131        if($In::Opt{"OldStyle"}) {
    42753132            $METHOD_PROBLEMS = "<h2>$Title ($ProblemsNum)</h2><hr/>\n".$METHOD_PROBLEMS;
    42763133        }
     
    42783135            $METHOD_PROBLEMS = "<h2>$Title <span".getStyle("M", $TargetSeverity, $ProblemsNum).">&nbsp;$ProblemsNum&nbsp;</span></h2><hr/>\n".$METHOD_PROBLEMS;
    42793136        }
    4280         $METHOD_PROBLEMS = "<a name='".get_Anchor("Method", $Level, $TargetSeverity)."'></a>\n".$METHOD_PROBLEMS;
     3137        $METHOD_PROBLEMS = "<a name='".getAnchor("Method", $Level, $TargetSeverity)."'></a>\n".$METHOD_PROBLEMS;
    42813138        $METHOD_PROBLEMS .= $TOP_REF."<br/>\n";
    42823139    }
     
    42843141}
    42853142
    4286 sub get_Report_TypeProblems($$)
     3143sub showType($$$)
     3144{
     3145    my ($Name, $Html, $LVer) = @_;
     3146    my $TType = $TypeInfo{$LVer}{$TName_Tid{$LVer}{$Name}}{"Type"};
     3147    if($Html) {
     3148        $Name = "<span class='ttype'>".$TType."</span> ".specChars($Name);
     3149    }
     3150    else {
     3151        $Name = $TType." ".$Name;
     3152    }
     3153    return $Name;
     3154}
     3155
     3156sub getReportTypeProblems($$)
    42873157{
    42883158    my ($TargetSeverity, $Level) = @_;
    42893159    my $TYPE_PROBLEMS = "";
     3160   
    42903161    my %ReportMap = ();
    42913162    my %TypeChanges_Sev = ();
     
    42973168        foreach my $Kind (keys(%{$TypeChanges{$Level}{$TypeName}}))
    42983169        {
    4299             my $Severity = $TypeProblems_Kind{$Level}{$Kind};
     3170            if($CompatRules{$Level}{$Kind}{"Severity"} ne $TargetSeverity) {
     3171                next;
     3172            }
    43003173           
    4301             if($Severity ne $TargetSeverity) {
    4302                 next;
    4303             }
    4304            
    4305             foreach my $Location (keys(%{$TypeChanges{$Level}{$TypeName}{$Kind}}))
     3174            foreach my $Loc (keys(%{$TypeChanges{$Level}{$TypeName}{$Kind}}))
    43063175            {
    43073176                $ReportMap{$ArchiveName}{$TypeName} = 1;
    4308                 $TypeChanges_Sev{$TypeName}{$Kind}{$Location} = $TypeChanges{$Level}{$TypeName}{$Kind}{$Location};
     3177                $TypeChanges_Sev{$TypeName}{$Kind}{$Loc} = $TypeChanges{$Level}{$TypeName}{$Kind}{$Loc};
    43093178            }
    43103179        }
     
    43143183    foreach my $ArchiveName (sort {lc($a) cmp lc($b)} keys(%ReportMap))
    43153184    {
    4316         my ($HEADER_REPORT, %NameSpace_Type) = ();
    4317         foreach my $TypeName (keys(%{$ReportMap{$ArchiveName}}))
    4318         {
     3185        my %NameSpace_Type = ();
     3186        foreach my $TypeName (keys(%{$ReportMap{$ArchiveName}})) {
    43193187            $NameSpace_Type{$TypeInfo{1}{$TName_Tid{1}{$TypeName}}{"Package"}}{$TypeName} = 1;
    43203188        }
     
    43263194            }
    43273195           
    4328             my @SortedTypes = sort {lc($a) cmp lc($b)} keys(%{$NameSpace_Type{$NameSpace}});
     3196            my @SortedTypes = sort {lc(showType($a, 0, 1)) cmp lc(showType($b, 0, 1))} keys(%{$NameSpace_Type{$NameSpace}});
    43293197            foreach my $TypeName (@SortedTypes)
    43303198            {
    43313199                my $TypeId = $TName_Tid{1}{$TypeName};
     3200               
    43323201                my $ProblemNum = 1;
    43333202                my $TYPE_REPORT = "";
    43343203                my (%Kinds_Locations, %Kinds_Target) = ();
     3204               
    43353205                foreach my $Kind (sort keys(%{$TypeChanges_Sev{$TypeName}}))
    43363206                {
     
    43453215                        $Kinds_Target{$Kind}{$Target} = 1;
    43463216                       
    4347                         my ($Change, $Effect) = ("", "");
    4348                         my %Problems = %{$TypeChanges_Sev{$TypeName}{$Kind}{$Location}};
     3217                        my %AddAttr = ();
    43493218                       
    4350                         my $Old_Value = $Problems{"Old_Value"};
    4351                         my $New_Value = $Problems{"New_Value"};
    4352                         my $Field_Type = $Problems{"Field_Type"};
    4353                         my $Field_Value = $Problems{"Field_Value"};
    4354                         my $Type_Type = $Problems{"Type_Type"};
    4355                        
    4356                         if($Kind eq "NonAbstract_Class_Added_Abstract_Method")
     3219                        if($Kind=~/Method/)
    43573220                        {
    4358                             $Change = "Abstract method ".black_Name($Target, 2)." has been added to this $Type_Type.";
    4359                             if($Level eq "Binary") {
    4360                                 $Effect = "This class became <b>abstract</b> and a client program may be interrupted by <b>InstantiationError</b> exception.";
     3221                            if(defined $MethodInfo{1}{$Target} and $MethodInfo{1}{$Target}{"Name"})
     3222                            {
     3223                                $AddAttr{"Method_Short"} = $Target;
     3224                                $AddAttr{"Class"} = getTypeName($MethodInfo{1}{$Target}{"Class"}, 1);
    43613225                            }
    4362                             else {
    4363                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method <b>".htmlSpecChars(get_Signature($Target, 2, "Short"))."</b> in <b>".htmlSpecChars(get_TypeName($MethodInfo{2}{$Target}{"Class"}, 2))."</b>.";
     3226                            elsif(defined $MethodInfo{2}{$Target} and $MethodInfo{2}{$Target}{"Name"})
     3227                            {
     3228                                $AddAttr{"Method_Short"} = $Target;
     3229                                $AddAttr{"Class"} = getTypeName($MethodInfo{2}{$Target}{"Class"}, 2);
    43643230                            }
    43653231                        }
    4366                         elsif($Kind eq "Abstract_Class_Added_Abstract_Method")
     3232                       
     3233                        my $ProblemAttr = $TypeChanges_Sev{$TypeName}{$Kind}{$Location};
     3234                       
     3235                        if(my $Change = applyMacroses($Level, $Kind, $CompatRules{$Level}{$Kind}{"Change"}, $ProblemAttr, \%AddAttr))
    43673236                        {
    4368                             $Change = "Abstract method ".black_Name($Target, 2)." has been added to this $Type_Type.";
    4369                             if($Level eq "Binary") {
    4370                                 $Effect = "No effect.";
    4371                             }
    4372                             else {
    4373                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method <b>".htmlSpecChars(get_Signature($Target, 2, "Short"))."</b> in <b>".htmlSpecChars(get_TypeName($MethodInfo{2}{$Target}{"Class"}, 2))."</b>.";
    4374                             }
    4375                         }
    4376                         elsif($Kind eq "Abstract_Class_Added_Abstract_Method_Invoked_By_Others")
    4377                         {
    4378                             $Change = "Abstract method ".black_Name($Target, 2)." has been added to this $Type_Type.";
    4379                             if($Level eq "Binary") {
    4380                                 $Effect = "A client program may be interrupted by <b>AbstractMethodError</b> exception. Added abstract method is called in 2nd library version by the method ".black_Name($Problems{"InvokedBy"}, 1)." and may not be implemented by old clients.";
    4381                             }
    4382                             else {
    4383                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method <b>".htmlSpecChars(get_Signature($Target, 2, "Short"))."</b> in <b>".htmlSpecChars(get_TypeName($MethodInfo{2}{$Target}{"Class"}, 2))."</b>.";
    4384                             }
    4385                         }
    4386                         elsif($Kind eq "Class_Removed_Abstract_Method"
    4387                         or $Kind eq "Interface_Removed_Abstract_Method")
    4388                         {
    4389                             $Change = "Abstract method ".black_Name($Target, 1)." has been removed from this $Type_Type.";
    4390                             if($Level eq "Binary") {
    4391                                 $Effect = "A client program may be interrupted by <b>NoSuchMethodError</b> exception.";
    4392                             }
    4393                             else {
    4394                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot find method <b>".htmlSpecChars(get_Signature($Target, 1, "Short"))."</b> in $Type_Type <b>".htmlSpecChars(get_TypeName($MethodInfo{1}{$Target}{"Class"}, 1))."</b>.";
    4395                             }
    4396                         }
    4397                         elsif($Kind eq "Interface_Added_Abstract_Method")
    4398                         {
    4399                             $Change = "Abstract method ".black_Name($Target, 2)." has been added to this $Type_Type.";
    4400                             if($Level eq "Binary") {
    4401                                 $Effect = "No effect.";
    4402                             }
    4403                             else {
    4404                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method <b>".htmlSpecChars(get_Signature($Target, 2, "Short"))."</b> in <b>".htmlSpecChars(get_TypeName($MethodInfo{2}{$Target}{"Class"}, 2))."</b>.";
    4405                             }
    4406                         }
    4407                         elsif($Kind eq "Interface_Added_Abstract_Method_Invoked_By_Others")
    4408                         {
    4409                             $Change = "Abstract method ".black_Name($Target, 2)." has been added to this $Type_Type.";
    4410                             if($Level eq "Binary") {
    4411                                 $Effect = "A client program may be interrupted by <b>AbstractMethodError</b> exception. Added abstract method is called in 2nd library version by the method ".black_Name($Problems{"InvokedBy"}, 1)." and may not be implemented by old clients.";
    4412                             }
    4413                             else {
    4414                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method <b>".htmlSpecChars(get_Signature($Target, 2, "Short"))."</b> in <b>".htmlSpecChars(get_TypeName($MethodInfo{2}{$Target}{"Class"}, 2))."</b>.";
    4415                             }
    4416                         }
    4417                         elsif($Kind eq "Class_Method_Became_Abstract")
    4418                         {
    4419                             $Change = "Method ".black_Name($Target, 1)." became <b>abstract</b>.";
    4420                             if($Level eq "Binary") {
    4421                                 $Effect = "A client program may be interrupted by <b>InstantiationError</b> exception.";
    4422                             }
    4423                             else {
    4424                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method <b>".htmlSpecChars(get_Signature($Target, 1, "Short"))."</b> in <b>".htmlSpecChars(get_TypeName($MethodInfo{1}{$Target}{"Class"}, 1))."</b>.";
    4425                             }
    4426                         }
    4427                         elsif($Kind eq "Class_Method_Became_NonAbstract")
    4428                         {
    4429                             $Change = "Abstract method ".black_Name($Target, 1)." became <b>non-abstract</b>.";
    4430                             if($Level eq "Binary") {
    4431                                 $Effect = "Some methods in this class may change behavior.";
    4432                             }
    4433                             else {
    4434                                 $Effect = "No effect.";
    4435                             }
    4436                         }
    4437                         elsif($Kind eq "Interface_Method_Became_NonDefault")
    4438                         {
    4439                             $Change = "Method ".black_Name($Target, 1)." became <b>non-default</b>.";
    4440                             if($Level eq "Binary") {
    4441                                 $Effect = "A client program may be interrupted by <b>AbstractMethodError</b> exception.";
    4442                             }
    4443                             else {
    4444                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method <b>".htmlSpecChars(get_Signature($Target, 1, "Short"))."</b> in <b>".htmlSpecChars(get_TypeName($MethodInfo{1}{$Target}{"Class"}, 1))."</b>.";
    4445                             }
    4446                         }
    4447                         elsif($Kind eq "Interface_Method_Became_Default")
    4448                         {
    4449                             $Change = "Method ".black_Name($Target, 1)." became <b>default</b>.";
    4450                             if($Level eq "Binary") {
    4451                                 $Effect = "No effect.";
    4452                             }
    4453                             else {
    4454                                 $Effect = "No effect.";
    4455                             }
    4456                         }
    4457                         elsif($Kind eq "Class_Overridden_Method")
    4458                         {
    4459                             $Change = "Method ".black_Name($Old_Value, 2)." has been overridden by ".black_Name($New_Value, 2);
    4460                             $Effect = "Method ".black_Name($New_Value, 2)." will be called instead of ".black_Name($Old_Value, 2)." in a client program.";
    4461                         }
    4462                         elsif($Kind eq "Class_Method_Moved_Up_Hierarchy")
    4463                         {
    4464                             $Change = "Method ".black_Name($Old_Value, 1)." has been moved up type hierarchy to ".black_Name($New_Value, 2);
    4465                             $Effect = "Method ".black_Name($New_Value, 2)." will be called instead of ".black_Name($Old_Value, 1)." in a client program.";
    4466                         }
    4467                         elsif($Kind eq "Abstract_Class_Added_Super_Interface")
    4468                         {
    4469                             $Change = "Added super-interface <b>".htmlSpecChars($Target)."</b>.";
    4470                             if($Level eq "Binary")
    4471                             {
    4472                                 $Effect = "No effect.";
    4473                             }
    4474                             else {
    4475                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method in <b>".htmlSpecChars($Target)."</b>.";
    4476                             }
    4477                         }
    4478                         elsif($Kind eq "Abstract_Class_Added_Super_Interface_Invoked_By_Others")
    4479                         {
    4480                             $Change = "Added super-interface <b>".htmlSpecChars($Target)."</b>.";
    4481                             if($Level eq "Binary") {
    4482                                 $Effect = "If abstract methods from an added super-interface must be implemented by client then it may be interrupted by <b>AbstractMethodError</b> exception.<br/><br/>Abstract method ".black_Name_S(htmlSpecChars($Problems{"Invoked"}))." from the added super-interface is called by the method ".black_Name($Problems{"InvokedBy"}, 2)." in 2nd library version and may not be implemented by old clients.";
    4483                             }
    4484                             else {
    4485                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method in <b>".htmlSpecChars($Target)."</b>.";
    4486                             }
    4487                         }
    4488                         elsif($Kind eq "Abstract_Class_Added_Super_Interface_With_Implemented_Methods")
    4489                         {
    4490                             $Change = "Added super-interface <b>".htmlSpecChars($Target)."</b>.";
    4491                             $Effect = "No effect.";
    4492                         }
    4493                         elsif($Kind eq "Interface_Added_Super_Interface")
    4494                         {
    4495                             $Change = "Added super-interface <b>".htmlSpecChars($Target)."</b>.";
    4496                             if($Level eq "Binary") {
    4497                                 $Effect = "No effect.";
    4498                             }
    4499                             else {
    4500                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method in <b>".htmlSpecChars($Target)."</b>.";
    4501                             }
    4502                         }
    4503                         elsif($Kind eq "Interface_Added_Super_Interface_Used_By_Others")
    4504                         {
    4505                             $Change = "Added super-interface <b>".htmlSpecChars($Target)."</b>.";
    4506                             if($Level eq "Binary")
    4507                             {
    4508                                 $Effect = "If abstract methods from an added super-interface must be implemented by client then it may be interrupted by <b>AbstractMethodError</b> exception.<br/><br/>Abstract method ".black_Name_S(htmlSpecChars($Problems{"Invoked"}))." from the added super-interface is called by the method ".black_Name($Problems{"InvokedBy"}, 2)." in 2nd library version and may not be implemented by old clients.";
    4509                             }
    4510                             else {
    4511                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method in <b>".htmlSpecChars($Target)."</b>.";
    4512                             }
    4513                         }
    4514                         elsif($Kind eq "Interface_Added_Super_Interface_With_Implemented_Methods")
    4515                         {
    4516                             $Change = "Added super-interface <b>".htmlSpecChars($Target)."</b>.";
    4517                             if($Level eq "Binary") {
    4518                                 $Effect = "No effect.";
    4519                             }
    4520                             else {
    4521                                 $Effect = "No effect.";
    4522                             }
    4523                         }
    4524                         elsif($Kind eq "Interface_Added_Super_Constant_Interface")
    4525                         {
    4526                             $Change = "Added super-interface <b>".htmlSpecChars($Target)."</b> containing constants only.";
    4527                             if($Level eq "Binary") {
    4528                                 $Effect = "A static field from a super-interface of a client class may hide a field (with the same name) inherited from a super-class and cause <b>IncompatibleClassChangeError</b> exception.";
    4529                             }
    4530                             else {
    4531                                 $Effect = "A static field from a super-interface of a client class may hide a field (with the same name) inherited from a super-class. Recompilation of a client class may be terminated with the message: reference to variable is ambiguous.";
    4532                             }
    4533                         }
    4534                         elsif($Kind eq "Interface_Removed_Super_Interface"
    4535                         or $Kind eq "Class_Removed_Super_Interface")
    4536                         {
    4537                             $Change = "Removed super-interface <b>".htmlSpecChars($Target)."</b>.";
    4538                             if($Level eq "Binary") {
    4539                                 $Effect = "A client program may be interrupted by <b>NoSuchMethodError</b> exception.";
    4540                             }
    4541                             else {
    4542                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot find method in $Type_Type <b>".htmlSpecChars($TypeName)."</b>.";
    4543                             }
    4544                         }
    4545                         elsif($Kind eq "Interface_Removed_Super_Constant_Interface")
    4546                         {
    4547                             $Change = "Removed super-interface <b>".htmlSpecChars($Target)."</b> containing constants only.";
    4548                             if($Level eq "Binary") {
    4549                                 $Effect = "No effect.";
    4550                             }
    4551                             else {
    4552                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot find variable in $Type_Type <b>".htmlSpecChars($TypeName)."</b>.";
    4553                             }
    4554                         }
    4555                         elsif($Kind eq "Added_Super_Class")
    4556                         {
    4557                             $Change = "Added super-class <b>".htmlSpecChars($Target)."</b>.";
    4558                             if($Level eq "Binary") {
    4559                                 $Effect = "A static field from a super-interface of a client class may hide a field (with the same name) inherited from new super-class and cause <b>IncompatibleClassChangeError</b> exception.";
    4560                             }
    4561                             else {
    4562                                 $Effect = "A static field from a super-interface of a client class may hide a field (with the same name) inherited from new super-class. Recompilation of a client class may be terminated with the message: reference to variable is ambiguous.";
    4563                             }
    4564                         }
    4565                         elsif($Kind eq "Abstract_Class_Added_Super_Abstract_Class")
    4566                         {
    4567                             $Change = "Added abstract super-class <b>".htmlSpecChars($Target)."</b>.";
    4568                             if($Level eq "Binary") {
    4569                                 $Effect = "No effect.";
    4570                             }
    4571                             else {
    4572                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method in <b>".htmlSpecChars($Target)."</b>.";
    4573                             }
    4574                         }
    4575                         elsif($Kind eq "Abstract_Class_Added_Super_Abstract_Class_Invoked_By_Others")
    4576                         {
    4577                             $Change = "Added abstract super-class <b>".htmlSpecChars($Target)."</b>.";
    4578                             if($Level eq "Binary") {
    4579                                 $Effect = "If abstract methods from an added super-class must be implemented by client then it may be interrupted by <b>AbstractMethodError</b> exception.<br/><br/>Abstract method ".black_Name_S(htmlSpecChars($Problems{"Invoked"}))." from the added abstract super-class is called by the method ".black_Name($Problems{"InvokedBy"}, 2)." in 2nd library version and may not be implemented by old clients.";
    4580                             }
    4581                             else {
    4582                                 $Effect = "Recompilation of a client program may be terminated with the message: a client class C is not abstract and does not override abstract method in <b>".htmlSpecChars($Target)."</b>.";
    4583                             }
    4584                         }
    4585                         elsif($Kind eq "Removed_Super_Class")
    4586                         {
    4587                             $Change = "Removed super-class <b>".htmlSpecChars($Target)."</b>.";
    4588                             if($Level eq "Binary") {
    4589                                 $Effect = "Access of a client program to the fields or methods of the old super-class may be interrupted by <b>NoSuchFieldError</b> or <b>NoSuchMethodError</b> exceptions.";
    4590                             }
    4591                             else {
    4592                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot find variable (or method) in <b>".htmlSpecChars($TypeName)."</b>.";
    4593                             }
    4594                         }
    4595                         elsif($Kind eq "Changed_Super_Class")
    4596                         {
    4597                             $Change = "Superclass has been changed from <b>".htmlSpecChars($Old_Value)."</b> to <b>".htmlSpecChars($New_Value)."</b>.";
    4598                             if($Level eq "Binary") {
    4599                                 $Effect = "1) Access of a client program to the fields or methods of the old super-class may be interrupted by <b>NoSuchFieldError</b> or <b>NoSuchMethodError</b> exceptions.<br/>2) A static field from a super-interface of a client class may hide a field (with the same name) inherited from new super-class and cause <b>IncompatibleClassChangeError</b> exception.";
    4600                             }
    4601                             else {
    4602                                 $Effect = "1) Recompilation of a client program may be terminated with the message: cannot find variable (or method) in <b>".htmlSpecChars($TypeName)."</b>.<br/>2) A static field from a super-interface of a client class may hide a field (with the same name) inherited from new super-class. Recompilation of a client class may be terminated with the message: reference to variable is ambiguous.";
    4603                             }
    4604                         }
    4605                         elsif($Kind eq "Class_Added_Field")
    4606                         {
    4607                             $Change = "Field <b>$Target</b> has been added to this class.";
    4608                             if($Level eq "Binary")
    4609                             {
    4610                                 $Effect = "No effect.";
    4611                                 # $Effect .= "<br/><b>NOTE</b>: A static field from a super-interface of a client class may hide an added field (with the same name) inherited from the super-class of a client class and cause <b>IncompatibleClassChangeError</b> exception.";
    4612                             }
    4613                             else
    4614                             {
    4615                                 $Effect = "No effect.";
    4616                                 # $Effect .= "<br/><b>NOTE</b>: A static field from a super-interface of a client class may hide an added field (with the same name) inherited from the super-class of a client class. Recompilation of a client class may be terminated with the message: reference to <b>$Target</b> is ambiguous.";
    4617                             }
    4618                         }
    4619                         elsif($Kind eq "Interface_Added_Field")
    4620                         {
    4621                             $Change = "Field <b>$Target</b> has been added to this interface.";
    4622                             if($Level eq "Binary") {
    4623                                 $Effect = "No effect.<br/><b>NOTE</b>: An added static field from a super-interface of a client class may hide a field (with the same name) inherited from the super-class of a client class and cause <b>IncompatibleClassChangeError</b> exception.";
    4624                             }
    4625                             else {
    4626                                 $Effect = "No effect.<br/><b>NOTE</b>: An added static field from a super-interface of a client class may hide a field (with the same name) inherited from the super-class of a client class. Recompilation of a client class may be terminated with the message: reference to <b>$Target</b> is ambiguous.";
    4627                             }
    4628                         }
    4629                         elsif($Kind eq "Renamed_Field")
    4630                         {
    4631                             $Change = "Field <b>$Target</b> has been renamed to <b>".htmlSpecChars($New_Value)."</b>.";
    4632                             if($Level eq "Binary") {
    4633                                 $Effect = "A client program may be interrupted by <b>NoSuchFieldError</b> exception.";
    4634                             }
    4635                             else {
    4636                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot find variable <b>$Target</b> in <b>".htmlSpecChars($TypeName)."</b>.";
    4637                             }
    4638                         }
    4639                         elsif($Kind eq "Renamed_Constant_Field")
    4640                         {
    4641                             if($Level eq "Binary") {
    4642                                 $Change = "Field <b>$Target</b> (".htmlSpecChars($Field_Type).") with the compile-time constant value <b>$Field_Value</b> has been renamed to <b>".htmlSpecChars($New_Value)."</b>.";
    4643                                 $Effect = "A client program may change behavior.";
    4644                             }
    4645                             else {
    4646                                 $Change = "Field <b>$Target</b> has been renamed to <b>".htmlSpecChars($New_Value)."</b>.";
    4647                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot find variable <b>$Target</b> in <b>".htmlSpecChars($TypeName)."</b>.";
    4648                             }
    4649                         }
    4650                         elsif($Kind eq "Removed_NonConstant_Field")
    4651                         {
    4652                             $Change = "Field <b>$Target</b> of type ".htmlSpecChars($Field_Type)." has been removed from this $Type_Type.";
    4653                             if($Level eq "Binary") {
    4654                                 $Effect = "A client program may be interrupted by <b>NoSuchFieldError</b> exception.";
    4655                             }
    4656                             else {
    4657                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot find variable <b>$Target</b> in <b>".htmlSpecChars($TypeName)."</b>.";
    4658                             }
    4659                         }
    4660                         elsif($Kind eq "Removed_Constant_Field")
    4661                         {
    4662                             $Change = "Field <b>$Target</b> (".htmlSpecChars($Field_Type).") with the compile-time constant value <b>$Field_Value</b> has been removed from this $Type_Type.";
    4663                             if($Level eq "Binary") {
    4664                                 $Effect = "A client program may change behavior.";
    4665                             }
    4666                             else {
    4667                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot find variable <b>$Target</b> in <b>".htmlSpecChars($TypeName)."</b>.";
    4668                             }
    4669                         }
    4670                         elsif($Kind eq "Changed_Field_Type")
    4671                         {
    4672                             $Change = "Type of field <b>$Target</b> has been changed from <span class='nowrap'><b>".htmlSpecChars($Old_Value)."</b></span> to <span class='nowrap'><b>".htmlSpecChars($New_Value)."</b></span>.";
    4673                             if($Level eq "Binary") {
    4674                                 $Effect = "A client program may be interrupted by <b>NoSuchFieldError</b> exception.";
    4675                             }
    4676                             else {
    4677                                 $Effect = "Recompilation of a client program may be terminated with the message: incompatible types, found: <b>".htmlSpecChars($Old_Value)."</b>, required: <b>".htmlSpecChars($New_Value)."</b>.";
    4678                             }
    4679                         }
    4680                         elsif($Kind eq "Changed_Field_Access")
    4681                         {
    4682                             $Change = "Access level of field <b>$Target</b> has been changed from <span class='nowrap'><b>$Old_Value</b></span> to <span class='nowrap'><b>$New_Value</b></span>.";
    4683                             if($Level eq "Binary") {
    4684                                 $Effect = "A client program may be interrupted by <b>IllegalAccessError</b> exception.";
    4685                             }
    4686                             else
    4687                             {
    4688                                 if($New_Value eq "package-private") {
    4689                                     $Effect = "Recompilation of a client program may be terminated with the message: <b>$Target</b> is not public in <b>".htmlSpecChars($TypeName)."</b>; cannot be accessed from outside package.";
    4690                                 }
    4691                                 else {
    4692                                     $Effect = "Recompilation of a client program may be terminated with the message: <b>$Target</b> has <b>$New_Value</b> access in <b>".htmlSpecChars($TypeName)."</b>.";
    4693                                 }
    4694                             }
    4695                         }
    4696                         elsif($Kind eq "Changed_Final_Field_Value")
    4697                         { # Binary Only
    4698                             $Change = "Value of final field <b>$Target</b> (<b>$Field_Type</b>) has been changed from <span class='nowrap'><b>".htmlSpecChars($Old_Value)."</b></span> to <span class='nowrap'><b>".htmlSpecChars($New_Value)."</b></span>.";
    4699                             $Effect = "Old value of the field will be inlined to the client code at compile-time and will be used instead of a new one.";
    4700                         }
    4701                         elsif($Kind eq "Changed_Final_Version_Field_Value")
    4702                         { # Binary Only
    4703                             $Change = "Value of final field <b>$Target</b> (<b>$Field_Type</b>) has been changed from <span class='nowrap'><b>".htmlSpecChars($Old_Value)."</b></span> to <span class='nowrap'><b>".htmlSpecChars($New_Value)."</b></span>.";
    4704                             $Effect = "Old value of the field will be inlined to the client code at compile-time and will be used instead of a new one.";
    4705                         }
    4706                         elsif($Kind eq "Field_Became_Final")
    4707                         {
    4708                             $Change = "Field <b>$Target</b> became <b>final</b>.";
    4709                             if($Level eq "Binary") {
    4710                                 $Effect = "A client program may be interrupted by <b>IllegalAccessError</b> exception when attempt to assign new values to the field.";
    4711                             }
    4712                             else {
    4713                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot assign a value to final variable $Target.";
    4714                             }
    4715                         }
    4716                         elsif($Kind eq "Field_Became_NonFinal")
    4717                         { # Binary Only
    4718                             $Change = "Field <b>$Target</b> became <b>non-final</b>.";
    4719                             $Effect = "Old value of the field will be inlined to the client code at compile-time and will be used instead of a new one.";
    4720                         }
    4721                         elsif($Kind eq "NonConstant_Field_Became_Static")
    4722                         { # Binary Only
    4723                             $Change = "Non-final field <b>$Target</b> became <b>static</b>.";
    4724                             $Effect = "A client program may be interrupted by <b>IncompatibleClassChangeError</b> exception.";
    4725                         }
    4726                         elsif($Kind eq "NonConstant_Field_Became_NonStatic")
    4727                         {
    4728                             if($Level eq "Binary") {
    4729                                 $Change = "Non-constant field <b>$Target</b> became <b>non-static</b>.";
    4730                                 $Effect = "A client program may be interrupted by <b>IncompatibleClassChangeError</b> exception.";
    4731                             }
    4732                             else {
    4733                                 $Change = "Field <b>$Target</b> became <b>non-static</b>.";
    4734                                 $Effect = "Recompilation of a client program may be terminated with the message: non-static variable <b>$Target</b> cannot be referenced from a static context.";
    4735                             }
    4736                         }
    4737                         elsif($Kind eq "Constant_Field_Became_NonStatic")
    4738                         { # Source Only
    4739                             $Change = "Field <b>$Target</b> became <b>non-static</b>.";
    4740                             $Effect = "Recompilation of a client program may be terminated with the message: non-static variable <b>$Target</b> cannot be referenced from a static context.";
    4741                         }
    4742                         elsif($Kind eq "Class_Became_Interface")
    4743                         {
    4744                             $Change = "This <b>class</b> became <b>interface</b>.";
    4745                             if($Level eq "Binary") {
    4746                                 $Effect = "A client program may be interrupted by <b>IncompatibleClassChangeError</b> or <b>InstantiationError</b> exception dependent on the usage of this class.";
    4747                             }
    4748                             else {
    4749                                 $Effect = "Recompilation of a client program may be terminated with the message: <b>".htmlSpecChars($TypeName)."</b> is abstract; cannot be instantiated.";
    4750                             }
    4751                         }
    4752                         elsif($Kind eq "Interface_Became_Class")
    4753                         {
    4754                             $Change = "This <b>interface</b> became <b>class</b>.";
    4755                             if($Level eq "Binary") {
    4756                                 $Effect = "A client program may be interrupted by <b>IncompatibleClassChangeError</b> exception.";
    4757                             }
    4758                             else {
    4759                                 $Effect = "Recompilation of a client program may be terminated with the message: interface expected.";
    4760                             }
    4761                         }
    4762                         elsif($Kind eq "Class_Became_Final")
    4763                         {
    4764                             $Change = "This class became <b>final</b>.";
    4765                             if($Level eq "Binary") {
    4766                                 $Effect = "A client program may be interrupted by <b>VerifyError</b> exception.";
    4767                             }
    4768                             else {
    4769                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot inherit from final <b>".htmlSpecChars($TypeName)."</b>.";
    4770                             }
    4771                         }
    4772                         elsif($Kind eq "Class_Became_Abstract")
    4773                         {
    4774                             $Change = "This class became <b>abstract</b>.";
    4775                             if($Level eq "Binary") {
    4776                                 $Effect = "A client program may be interrupted by <b>InstantiationError</b> exception.";
    4777                             }
    4778                             else {
    4779                                 $Effect = "Recompilation of a client program may be terminated with the message: <b>".htmlSpecChars($TypeName)."</b> is abstract; cannot be instantiated.";
    4780                             }
    4781                         }
    4782                         elsif($Kind eq "Removed_Class")
    4783                         {
    4784                             $Change = "This class has been removed.";
    4785                             if($Level eq "Binary") {
    4786                                 $Effect = "A client program may be interrupted by <b>NoClassDefFoundError</b> exception.";
    4787                             }
    4788                             else {
    4789                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot find class <b>".htmlSpecChars($TypeName)."</b>.";
    4790                             }
    4791                         }
    4792                         elsif($Kind eq "Removed_Interface")
    4793                         {
    4794                             $Change = "This interface has been removed.";
    4795                             if($Level eq "Binary") {
    4796                                 $Effect = "A client program may be interrupted by <b>NoClassDefFoundError</b> exception.";
    4797                             }
    4798                             else {
    4799                                 $Effect = "Recompilation of a client program may be terminated with the message: cannot find class <b>".htmlSpecChars($TypeName)."</b>.";
    4800                             }
    4801                         }
    4802                         elsif($Kind eq "Removed_Annotation")
    4803                         {
    4804                             $Change = "This annotation type has been removed.";
    4805                             if($Level eq "Binary") {
    4806                                 $Effect = "No effect.";
    4807                             }
    4808                             else {
    4809                                 $Effect = "Recompilation of a client program may be terminated with the error message: cannot find symbol <b>\@".htmlSpecChars($TypeName)."</b>.";
    4810                             }
    4811                         }
    4812                         if($Change)
    4813                         {
    4814                             $TYPE_REPORT .= "<tr><th>$ProblemNum</th><td>".$Change."</td><td>".$Effect."</td></tr>\n";
     3237                            my $Effect = applyMacroses($Level, $Kind, $CompatRules{$Level}{$Kind}{"Effect"}, $ProblemAttr, \%AddAttr);
     3238                           
     3239                            $TYPE_REPORT .= "<tr>\n<th>$ProblemNum</th>\n<td>".$Change."</td>\n<td>".$Effect."</td>\n</tr>\n";
    48153240                            $ProblemNum += 1;
    48163241                            $ProblemsNum += 1;
    4817                             $Kinds_Locations{$Kind}{$Location} = 1;
    48183242                        }
    48193243                    }
     
    48273251                    }
    48283252                   
    4829                     my $ShowType = $TypeName;
     3253                    my $ShowType = showType($TypeName, 1, 1);
    48303254                    if($NameSpace)
    48313255                    {
    4832                         $TYPE_REPORT = cut_Namespace($TYPE_REPORT, $NameSpace);
    4833                         $ShowType = cut_Namespace($ShowType, $NameSpace);
    4834                         $Affected = cut_Namespace($Affected, $NameSpace);
     3256                        $TYPE_REPORT = cutNs($TYPE_REPORT, $NameSpace);
     3257                        $ShowType = cutNs($ShowType, $NameSpace);
     3258                        $Affected = cutNs($Affected, $NameSpace);
    48353259                    }
    48363260                   
    4837                     $TYPE_PROBLEMS .= $ContentSpanStart."<span class='ext'>[+]</span> ".htmlSpecChars($ShowType);
    4838                     if($OldStyle) {
     3261                    $TYPE_PROBLEMS .= $ContentSpanStart."<span class='ext'>[+]</span> ".$ShowType;
     3262                    if($In::Opt{"OldStyle"}) {
    48393263                        $TYPE_PROBLEMS .= " ($ProblemNum)";
    48403264                    }
     
    48613285            $Title = "Other Changes in Data Types";
    48623286        }
    4863         if($OldStyle) {
     3287        if($In::Opt{"OldStyle"}) {
    48643288            $TYPE_PROBLEMS = "<h2>$Title ($ProblemsNum)</h2><hr/>\n".$TYPE_PROBLEMS;
    48653289        }
     
    48673291            $TYPE_PROBLEMS = "<h2>$Title <span".getStyle("T", $TargetSeverity, $ProblemsNum).">&nbsp;$ProblemsNum&nbsp;</span></h2><hr/>\n".$TYPE_PROBLEMS;
    48683292        }
    4869         $TYPE_PROBLEMS = "<a name='".get_Anchor("Type", $Level, $TargetSeverity)."'></a>\n".$TYPE_PROBLEMS;
     3293        $TYPE_PROBLEMS = "<a name='".getAnchor("Type", $Level, $TargetSeverity)."'></a>\n".$TYPE_PROBLEMS;
    48703294        $TYPE_PROBLEMS .= $TOP_REF."<br/>\n";
    48713295    }
     
    48733297}
    48743298
    4875 sub cut_Namespace($$)
     3299sub cutNs($$)
    48763300{
    48773301    my ($N, $Ns) = @_;
     
    48853309   
    48863310    my $LIMIT = 10;
    4887     if(defined $AffectLimit) {
    4888         $LIMIT = $AffectLimit;
    4889     }
    4890    
    4891     my @Kinds = sort keys(%{$Kinds_Locations});
    4892     my %KLocs = ();
    4893     foreach my $Kind (@Kinds)
    4894     {
    4895         my @Locs = sort {$a=~/retval/ cmp $b=~/retval/} sort {length($a)<=>length($b)} sort keys(%{$Kinds_Locations->{$Kind}});
    4896         $KLocs{$Kind} = \@Locs;
    4897     }
    4898    
    4899     my %SymLocKind = ();
    4900     foreach my $Method (sort keys(%{$TypeProblemsIndex{$Target_TypeName}}))
    4901     {
    4902         if($Method eq ".client_method") {
    4903             next;
    4904         }
    4905        
    4906         foreach my $Kind (@Kinds)
    4907         {
    4908             foreach my $Loc (@{$KLocs{$Kind}})
    4909             {
    4910                 if(not defined $CompatProblems{$Method}{$Kind}{$Loc}) {
     3311    if(defined $In::Opt{"AffectLimit"}) {
     3312        $LIMIT = $In::Opt{"AffectLimit"};
     3313    }
     3314   
     3315    my %SymSel = ();
     3316   
     3317    foreach my $Kind (sort keys(%{$Kinds_Locations}))
     3318    {
     3319        my @Locs = sort {(index($a, "retval")!=-1) cmp (index($b, "retval")!=-1)} sort {length($a)<=>length($b)} sort keys(%{$Kinds_Locations->{$Kind}});
     3320       
     3321        foreach my $Loc (@Locs)
     3322        {
     3323            foreach my $Method (keys(%{$TypeProblemsIndex{$Level}{$Target_TypeName}{$Kind}{$Loc}}))
     3324            {
     3325                if($Method eq ".client_method") {
    49113326                    next;
    49123327                }
    49133328               
    4914                 my $Type_Name = $CompatProblems{$Method}{$Kind}{$Loc}{"Type_Name"};
    4915                 if($Type_Name ne $Target_TypeName) {
    4916                     next;
    4917                 }
    4918                
    4919                 $SymLocKind{$Method}{$Loc}{$Kind} = 1;
    4920                 last;
    4921             }
    4922         }
    4923     }
    4924    
    4925     %KLocs = (); # clear
    4926    
    4927     if(not keys(%SymLocKind)) {
     3329                if(not defined $SymSel{$Method})
     3330                {
     3331                    $SymSel{$Method}{"Kind"} = $Kind;
     3332                    $SymSel{$Method}{"Loc"} = $Loc;
     3333                }
     3334            }
     3335        }
     3336    }
     3337   
     3338    my $Total = keys(%SymSel);
     3339   
     3340    if(not $Total) {
    49283341        return "";
    49293342    }
    49303343   
    4931     my %SymSel = ();
    4932     my $Num = 0;
    4933     foreach my $Method (sort keys(%SymLocKind))
    4934     {
    4935         LOOP: foreach my $Loc (sort {$a=~/retval/ cmp $b=~/retval/} sort {length($a)<=>length($b)} sort keys(%{$SymLocKind{$Method}}))
    4936         {
    4937             foreach my $Kind (sort keys(%{$SymLocKind{$Method}{$Loc}}))
    4938             {
    4939                 $SymSel{$Method}{"Loc"} = $Loc;
    4940                 $SymSel{$Method}{"Kind"} = $Kind;
    4941                 last LOOP;
    4942             }
    4943         }
    4944        
    4945         $Num += 1;
    4946        
    4947         if($Num>=$LIMIT) {
    4948             last;
    4949         }
    4950     }
    4951    
    49523344    my $Affected = "";
     3345    my $SNum = 0;
    49533346   
    49543347    foreach my $Method (sort {lc($a) cmp lc($b)} keys(%SymSel))
     
    49613354        my $Pos = getParamPos($PName, $Method, 1);
    49623355       
    4963         $Affected .= "<span class='iname_a'>".get_Signature($Method, 1, "HTML|Italic|Param|Class|Target=".$Pos)."</span><br/>";
     3356        $Affected .= "<span class='iname_a'>".getSignature($Method, 1, "HTML|Italic|Param|Class|Target=".$Pos)."</span><br/>";
    49643357        $Affected .= "<div class='affect'>".$Desc."</div>\n";
    4965     }
    4966    
    4967     if(keys(%SymLocKind)>$LIMIT) {
     3358       
     3359        if(++$SNum>=$LIMIT) {
     3360            last;
     3361        }
     3362    }
     3363   
     3364    if($Total>$LIMIT) {
    49683365        $Affected .= " <b>...</b>\n<br/>\n"; # and others ...
    49693366    }
     
    49723369    if($Affected)
    49733370    {
    4974         my $Num = keys(%SymLocKind);
    4975         my $Per = show_number($Num*100/keys(%CheckedMethods));
     3371        my $Per = showNum($Total*100/keys(%CheckedMethods));
    49763372        $Affected =  $ContentDivStart.$Affected.$ContentDivEnd;
    4977         $Affected =  $ContentSpanStart_Affected."[+] affected methods: $Num ($Per\%)".$ContentSpanEnd.$Affected;
    4978     }
    4979    
    4980     return ($Affected);
     3373        $Affected =  $ContentSpanStart_Affected."[+] affected methods: $Total ($Per\%)".$ContentSpanEnd.$Affected;
     3374    }
     3375   
     3376    return $Affected;
    49813377}
    49823378
     
    49913387    $Location=~s/\.[^.]+?\Z//;
    49923388   
    4993     my %TypeAttr = get_Type($MethodInfo{1}{$Method}{"Class"}, 1);
    4994     my $Type_Type = $TypeAttr{"Type"};
     3389    my $TypeAttr = getType($MethodInfo{1}{$Method}{"Class"}, 1);
     3390    my $Type_Type = $TypeAttr->{"Type"};
    49953391   
    49963392    my $ABSTRACT_M = $MethodInfo{1}{$Method}{"Abstract"}?" abstract":"";
    4997     my $ABSTRACT_C = $TypeAttr{"Abstract"}?" abstract":"";
     3393    my $ABSTRACT_C = $TypeAttr->{"Abstract"}?" abstract":"";
    49983394    my $METHOD_TYPE = $MethodInfo{1}{$Method}{"Constructor"}?"constructor":"method";
    49993395   
    50003396    if($Kind eq "Class_Overridden_Method" or $Kind eq "Class_Method_Moved_Up_Hierarchy") {
    5001         return "Method '".highLight_Signature($New_Value, 2)."' will be called instead of this method in a client program.";
    5002     }
    5003     elsif($TypeProblems_Kind{$Level}{$Kind})
     3397        return "Method '".getSignature($New_Value, 2, "Class|HTML|Italic")."' will be called instead of this method in a client program.";
     3398    }
     3399    elsif($CompatRules{$Level}{$Kind}{"Kind"} eq "Types")
    50043400    {
    50053401        my %MInfo = %{$MethodInfo{1}{$Method}};
    50063402       
    50073403        if($Location eq "this") {
    5008             return "This$ABSTRACT_M $METHOD_TYPE is from \'".htmlSpecChars($Type_Name)."\'$ABSTRACT_C $Type_Type.";
     3404            return "This$ABSTRACT_M $METHOD_TYPE is from \'".specChars($Type_Name)."\'$ABSTRACT_C $Type_Type.";
    50093405        }
    50103406       
     
    50143410        { # return value
    50153411            if($Location=~/\./) {
    5016                 push(@Sentence_Parts, "Field \'".htmlSpecChars($Location)."\' in return value");
     3412                push(@Sentence_Parts, "Field \'".specChars($Location)."\' in the return value");
    50173413            }
    50183414            else {
     
    50243420        elsif($Location=~/this/)
    50253421        { # "this" reference
    5026             push(@Sentence_Parts, "Field \'".htmlSpecChars($Location)."\' in the object");
     3422            push(@Sentence_Parts, "Field \'".specChars($Location)."\' in the object");
    50273423           
    50283424            $TypeID = $MInfo{"Class"};
     
    50343430           
    50353431            if($Location=~/\./) {
    5036                 push(@Sentence_Parts, "Field \'".htmlSpecChars($Location)."\' in ".showPos($PPos)." parameter");
     3432                push(@Sentence_Parts, "Field \'".specChars($Location)."\' in ".showPos($PPos)." parameter");
    50373433            }
    50383434            else {
     
    50583454       
    50593455        if($TypeInfo{1}{$TypeID_Problem}{"Name"} eq $Type_Name) {
    5060             push(@Sentence_Parts, "has type \'".htmlSpecChars($Type_Name)."\'.");
     3456            push(@Sentence_Parts, "is of type \'".specChars($Type_Name)."\'.");
    50613457        }
    50623458        else {
    5063             push(@Sentence_Parts, "has base type \'".htmlSpecChars($Type_Name)."\'.");
     3459            push(@Sentence_Parts, "has base type \'".specChars($Type_Name)."\'.");
    50643460        }
    50653461    }
     
    50693465sub getParamPos($$$)
    50703466{
    5071     my ($Name, $Method, $LibVersion) = @_;
    5072    
    5073     if(defined $MethodInfo{$LibVersion}{$Method}
    5074     and defined $MethodInfo{$LibVersion}{$Method}{"Param"})
    5075     {
    5076         my $Info = $MethodInfo{$LibVersion}{$Method};
     3467    my ($Name, $Method, $LVer) = @_;
     3468   
     3469    if(defined $MethodInfo{$LVer}{$Method}
     3470    and defined $MethodInfo{$LVer}{$Method}{"Param"})
     3471    {
     3472        my $Info = $MethodInfo{$LVer}{$Method};
    50773473        foreach (keys(%{$Info->{"Param"}}))
    50783474        {
     
    50963492sub getFieldType($$$)
    50973493{
    5098     my ($Location, $TypeId, $LibVersion) = @_;
     3494    my ($Location, $TypeId, $LVer) = @_;
    50993495   
    51003496    my @Fields = split(/\./, $Location);
     
    51023498    foreach my $Name (@Fields)
    51033499    {
    5104         my %Info = get_BaseType($TypeId, $LibVersion);
    5105        
    5106         foreach my $N (keys(%{$Info{"Fields"}}))
     3500        my $TInfo = getBaseType($TypeId, $LVer);
     3501       
     3502        foreach my $N (keys(%{$TInfo->{"Fields"}}))
    51073503        {
    51083504            if($N eq $Name)
    51093505            {
    5110                 $TypeId = $Info{"Fields"}{$N}{"Type"};
     3506                $TypeId = $TInfo->{"Fields"}{$N}{"Type"};
    51113507                last;
    51123508            }
     
    51243520}
    51253521
    5126 sub getRelPath($$)
    5127 {
    5128     my ($A, $B) = @_;
    5129     return abs2rel($A, get_dirname($B));
    5130 }
    5131 
    51323522sub createReport()
    51333523{
    5134     if($JoinReport)
    5135     { # --stdout
     3524    if($In::Opt{"JoinReport"}) {
    51363525        writeReport("Join", getReport("Join"));
    51373526    }
    5138     elsif($DoubleReport)
     3527    elsif($In::Opt{"DoubleReport"})
    51393528    { # default
    51403529        writeReport("Binary", getReport("Binary"));
    51413530        writeReport("Source", getReport("Source"));
    51423531    }
    5143     elsif($BinaryOnly)
     3532    elsif($In::Opt{"BinaryOnly"})
    51443533    { # --binary
    51453534        writeReport("Binary", getReport("Binary"));
    51463535    }
    5147     elsif($SourceOnly)
     3536    elsif($In::Opt{"SourceOnly"})
    51483537    { # --source
    51493538        writeReport("Source", getReport("Source"));
     
    51513540}
    51523541
    5153 sub getCssStyles()
    5154 {
    5155     my $CssStyles = "
    5156     body {
    5157         font-family:Arial, sans-serif;
    5158         background-color:White;
    5159         color:Black;
    5160     }
    5161     hr {
    5162         color:Black;
    5163         background-color:Black;
    5164         height:1px;
    5165         border:0;
    5166     }
    5167     h1 {
    5168         margin-bottom:0px;
    5169         padding-bottom:0px;
    5170         font-size:1.625em;
    5171     }
    5172     h2 {
    5173         margin-bottom:0px;
    5174         padding-bottom:0px;
    5175         font-size:1.25em;
    5176         white-space:nowrap;
    5177     }
    5178     div.symbols {
    5179         color:#003E69;
    5180     }
    5181     div.symbols i {
    5182         color:Brown;
    5183     }
    5184     span.section {
    5185         font-weight:bold;
    5186         cursor:pointer;
    5187         color:#003E69;
    5188         white-space:nowrap;
    5189         margin-left:5px;
    5190     }
    5191     span:hover.section {
    5192         color:#336699;
    5193     }
    5194     span.sect_aff {
    5195         cursor:pointer;
    5196         margin-left:7px;
    5197         padding-left:15px;
    5198         font-size:0.875em;
    5199         color:#cc3300;
    5200     }
    5201     span.ext {
    5202         font-weight:100;
    5203     }
    5204     span.jar {
    5205         color:#cc3300;
    5206         font-size:0.875em;
    5207         font-weight:bold;
    5208     }
    5209     div.jar_list {
    5210         padding-left:5px;
    5211         font-size:0.94em;
    5212     }
    5213     span.pkg_t {
    5214         color:#408080;
    5215         font-size:0.875em;
    5216     }
    5217     span.pkg {
    5218         color:#408080;
    5219         font-size:0.875em;
    5220         font-weight:bold;
    5221     }
    5222     span.cname {
    5223         color:Green;
    5224         font-size:0.875em;
    5225         font-weight:bold;
    5226     }
    5227     span.iname_b {
    5228         font-weight:bold;
    5229         font-size:1.1em;
    5230     }
    5231     span.iname_a {
    5232         color:#333333;
    5233         font-weight:bold;
    5234         font-size:0.94em;
    5235     }
    5236     span.sym_p {
    5237         font-weight:normal;