Index: asc/src/java/macromedia/asc/semantics/Emitter.java =================================================================== *** asc/src/java/macromedia/asc/semantics/Emitter.java (revision 744) --- asc/src/java/macromedia/asc/semantics/Emitter.java (working copy) *************** *** 146,165 **** protected void StartMethod() { ! StartMethod("", 0, 0, 0, false, 0); } protected void StartMethod(final String name, int param_count, int local_count) { ! StartMethod(name, param_count, local_count, 0, false, 0); } ! protected void StartMethod(final String name, int param_count, int local_count, int temp_count, boolean needs_activation, int needs_arguments) { doing_method = true; if (impl != null) { ! impl.StartMethod(name, param_count, local_count, temp_count, needs_activation, needs_arguments); } } --- 146,169 ---- protected void StartMethod() { ! StartMethod("", 0, 0, 0, false, 0, null); } protected void StartMethod(final String name, int param_count, int local_count) { ! StartMethod(name, param_count, local_count, 0, false, 0, null); } ! protected void StartMethod(final String name, int param_count, int local_count, int temp_count, boolean needs_activation, int needs_arguments) ! { ! StartMethod(name, param_count, local_count, 0, false, 0, null); ! } ! protected void StartMethod(final String name, int param_count, int local_count, int temp_count, boolean needs_activation, int needs_arguments, final String debug_name) { doing_method = true; if (impl != null) { ! impl.StartMethod(name, param_count, local_count, temp_count, needs_activation, needs_arguments, debug_name); } } Index: asc/src/java/macromedia/asc/semantics/CodeGenerator.java =================================================================== *** asc/src/java/macromedia/asc/semantics/CodeGenerator.java (revision 744) --- asc/src/java/macromedia/asc/semantics/CodeGenerator.java (working copy) *************** *** 3562,3568 **** frame.activationIsExposed = needs_activation; frame.registerScopeIndex = needs_activation ? -1 : (cx.getScopes().size()-1); ! StartMethod(frame.functionName,frame.maxParams,frame.maxLocals,0,needs_activation,node.needsArguments); // If this is a constructor, then insert a call to the base constructor, // and the instance initializer --- 3562,3574 ---- frame.activationIsExposed = needs_activation; frame.registerScopeIndex = needs_activation ? -1 : (cx.getScopes().size()-1); ! String coverageName = node.debug_name; ! if (coverageName == null || coverageName.length() == 0) ! { ! coverageName = frame.functionName; ! } ! ! StartMethod(frame.functionName,frame.maxParams,frame.maxLocals,0,needs_activation,node.needsArguments,node.debug_name); // If this is a constructor, then insert a call to the base constructor, // and the instance initializer Index: asc/src/java/macromedia/asc/semantics/FlowGraphEmitter.java =================================================================== *** asc/src/java/macromedia/asc/semantics/FlowGraphEmitter.java (revision 744) --- asc/src/java/macromedia/asc/semantics/FlowGraphEmitter.java (working copy) *************** *** 468,474 **** } ! public void StartMethod(String name, int param_count, int local_count, int temp_count, boolean needs_activation, int needs_arguments) { if (show_instructions) { --- 468,474 ---- } ! public void StartMethod(String name, int param_count, int local_count, int temp_count, boolean needs_activation, int needs_arguments, String debug_name) { if (show_instructions) { Index: asc/src/java/macromedia/asc/embedding/avmplus/DebugInfo.java =================================================================== *** asc/src/java/macromedia/asc/embedding/avmplus/DebugInfo.java (revision 744) --- asc/src/java/macromedia/asc/embedding/avmplus/DebugInfo.java (working copy) *************** *** 23,27 **** --- 23,29 ---- String debug_file; boolean suppress_debug_method = false; boolean debug_file_dirty = false; + String debug_function; + boolean debug_function_dirty = false; } Index: asc/src/java/macromedia/asc/embedding/avmplus/ActionBlockEmitter.java =================================================================== *** asc/src/java/macromedia/asc/embedding/avmplus/ActionBlockEmitter.java (revision 744) --- asc/src/java/macromedia/asc/embedding/avmplus/ActionBlockEmitter.java (working copy) *************** *** 776,785 **** protected void StartMethod() { ! StartMethod("", 0, 0, 0, false, 0); } ! protected void StartMethod(final String name, int param_count, int local_count, int temp_count, boolean needs_activation, int needs_arguments) { if (show_instructions) { --- 776,785 ---- protected void StartMethod() { ! StartMethod("", 0, 0, 0, false, 0, null); } ! protected void StartMethod(final String name, int param_count, int local_count, int temp_count, boolean needs_activation, int needs_arguments, String debug_name) { if (show_instructions) { *************** *** 813,818 **** --- 813,821 ---- debug_info.debug_linenum_dirty = true; debug_info.suppress_debug_method = (name.indexOf("$iinit") != -1 || name.indexOf("$cinit") != -1); + debug_info.debug_function = debug_name; + debug_info.debug_function_dirty = true; + sets_dxns = false; } *************** *** 7743,7752 **** --- 7746,7765 ---- DebugLine(debug_info.debug_linenum); debug_info.debug_linenum_dirty = false; + + // Spit out calls to a global coverage-monitoring function + if (debug_info.debug_function != null && debug_info.debug_function.length() > 0) + { + RecordCoverage(debug_info.debug_function, debug_info.debug_linenum); + } } } } + public void RecordCoverage(String functionName, int linenum) + { + } + public void reorderMainScript() { ab.scripts.add(ab.scripts.remove(0)); Index: compiler/src/java/flex2/tools/PreLink.java =================================================================== *** compiler/src/java/flex2/tools/PreLink.java (revision 744) --- compiler/src/java/flex2/tools/PreLink.java (working copy) *************** *** 1147,1152 **** --- 1147,1154 ---- " }", lineSep, " }", lineSep, codegenRslCompleteListener(configuration, lineSep), + configuration.getCompilerConfiguration().coverage() + ? " private function coverageDependency():void { coverage(null, 0); }" : "", "}", lineSep, lineSep, "}", lineSep, }; Index: compiler/src/java/flex2/configuration_en.properties =================================================================== *** compiler/src/java/flex2/configuration_en.properties (revision 744) --- compiler/src/java/flex2/configuration_en.properties (working copy) *************** *** 187,192 **** --- 187,193 ---- Brief=${program} [options] [defaultVar]\nUse '${program} -help' for more information.\n\n compiler.allow-source-path-overlap=checks if a source-path entry is a subdirectory of another source-path entry. It helps make the package names of MXML components unambiguous. + compiler.coverage=generates code coverage information compiler.debug=generates a movie that is suitable for debugging compiler.define=define a global AS3 conditional compilation definition, e.g. -define=CONFIG::debugging,true or -define+=CONFIG::debugging,true (to append to existing definitions in flex-config.xml) compiler.defaults-css-url=defines the location of the default style sheet. Setting this option overrides the implicit use of the defaults.css style sheet in the framework.swc file. Index: compiler/src/java/flex2/compiler/i18n/Compiler.java =================================================================== *** compiler/src/java/flex2/compiler/i18n/Compiler.java (revision 744) --- compiler/src/java/flex2/compiler/i18n/Compiler.java (working copy) *************** *** 52,57 **** --- 52,58 ---- configuration = compilerConfig; asc = new flex2.compiler.as3.Compiler(new flex2.compiler.as3.Configuration() { + public boolean coverage() { return false; } public boolean debug() { return false; } public boolean profile() { return false; } public boolean strict() { return true; } Index: compiler/src/java/flex2/compiler/as3/Configuration.java =================================================================== *** compiler/src/java/flex2/compiler/as3/Configuration.java (revision 744) --- compiler/src/java/flex2/compiler/as3/Configuration.java (working copy) *************** *** 22,27 **** --- 22,29 ---- * Generate SWFs for debugging */ boolean debug(); + + boolean coverage(); int dialect(); boolean adjustOpDebugLine(); Index: compiler/src/java/flex2/compiler/as3/Compiler.java =================================================================== *** compiler/src/java/flex2/compiler/as3/Compiler.java (revision 744) --- compiler/src/java/flex2/compiler/as3/Compiler.java (working copy) *************** *** 673,678 **** --- 673,679 ---- LineNumberMap map = (LineNumberMap) context.getAttribute("LineNumberMap"); Emitter emitter = new BytecodeEmitter(cx, unit.getSource(), configuration != null && configuration.debug(), + configuration != null && configuration.coverage(), (configuration != null && configuration.adjustOpDebugLine()) ? map : null); cx.pushScope(node.frame); Index: compiler/src/java/flex2/compiler/as3/BytecodeEmitter.java =================================================================== *** compiler/src/java/flex2/compiler/as3/BytecodeEmitter.java (revision 744) --- compiler/src/java/flex2/compiler/as3/BytecodeEmitter.java (working copy) *************** *** 14,21 **** --- 14,24 ---- import flex2.compiler.Source; import flex2.compiler.util.LineNumberMap; import macromedia.asc.embedding.avmplus.ActionBlockEmitter; + import macromedia.asc.embedding.avmplus.RuntimeConstants; + import macromedia.asc.semantics.ObjectValue; import macromedia.asc.util.ByteList; import macromedia.asc.util.Context; + import macromedia.asc.util.Namespaces; import macromedia.asc.util.StringPrintWriter; import java.io.File; *************** *** 29,43 **** { public BytecodeEmitter(Context cx, Source source, boolean debug) { ! this(cx, source, debug, null); } ! public BytecodeEmitter(Context cx, Source source, boolean debug, LineNumberMap map) { super(cx, source != null ? source.getName() : null, new StringPrintWriter(), new StringPrintWriter(), false, false, false, debug); this.map = map; this.source = source; this.cx = cx; if (debug) { --- 32,47 ---- { public BytecodeEmitter(Context cx, Source source, boolean debug) { ! this(cx, source, debug, false, null); } ! public BytecodeEmitter(Context cx, Source source, boolean debug, boolean coverage, LineNumberMap map) { super(cx, source != null ? source.getName() : null, new StringPrintWriter(), new StringPrintWriter(), false, false, false, debug); this.map = map; this.source = source; this.cx = cx; + this.coverage = coverage; if (debug) { *************** *** 50,55 **** --- 54,61 ---- private Source source; private String currentFileName; private Context cx; + + private boolean coverage; // C: not used when debug is false... private Set lines; *************** *** 154,159 **** --- 160,186 ---- super.DebugLine(code, newLine); } } + + public void RecordCoverage(String functionName, int linenum) + { + if (!source.isDebuggable() || !coverage) + { + return; + } + + int newLine = calculateLineNumber(linenum); + if (newLine != -1) + { + final String COVERAGE = "coverage"; + ObjectValue n = cx.publicNamespace(); + Namespaces ns = cx.statics.internNamespaces.intern(n); + FindProperty(COVERAGE, ns, true, true, false); + PushString(functionName); + PushNumber(newLine, RuntimeConstants.TYPE_int); + CallProperty(COVERAGE, ns, 2, true, false, false, false); + Pop(); + } + } private int calculateLineNumber(int line) { Index: compiler/src/java/flex2/compiler/common/CompilerConfiguration.java =================================================================== *** compiler/src/java/flex2/compiler/common/CompilerConfiguration.java (revision 744) --- compiler/src/java/flex2/compiler/common/CompilerConfiguration.java (working copy) *************** *** 502,507 **** --- 502,535 ---- } // + // 'compiler.coverage' option + // + + private boolean coverage; + + public boolean coverage() + { + return coverage; + } + + public void cfgCoverage( ConfigurationValue cv, boolean coverage ) + { + this.coverage = coverage; + this.generateDebugTags = this.generateDebugTags || coverage; + } + + public static ConfigurationInfo getCoverageInfo() + { + return new AdvancedConfigurationInfo() + { + public String[] getPrerequisites() + { + return new String[] { "debug" }; + } + }; + } + + // // 'compiler.debug' option // Index: compiler/src/java/flex2/compiler/mxml/InterfaceCompiler.java =================================================================== *** compiler/src/java/flex2/compiler/mxml/InterfaceCompiler.java (revision 744) --- compiler/src/java/flex2/compiler/mxml/InterfaceCompiler.java (working copy) *************** *** 113,119 **** mimeTypes = new String[]{MimeMappings.MXML}; asc = new flex2.compiler.as3.Compiler(new flex2.compiler.as3.Configuration() { ! public boolean debug() { return false; } public boolean profile() { return false; } public boolean strict() { return ascConfiguration.strict(); } public int dialect() { return ascConfiguration.dialect(); } --- 113,120 ---- mimeTypes = new String[]{MimeMappings.MXML}; asc = new flex2.compiler.as3.Compiler(new flex2.compiler.as3.Configuration() { ! public boolean coverage() { return false; } ! public boolean debug() { return false; } public boolean profile() { return false; } public boolean strict() { return ascConfiguration.strict(); } public int dialect() { return ascConfiguration.dialect(); }