📄 switchgenerator.java
字号:
/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */package org.mozilla.javascript.tools.idswitch;import org.mozilla.javascript.EvaluatorException;import org.mozilla.javascript.tools.ToolErrorReporter;public class SwitchGenerator { String v_switch_label = "L0"; String v_label = "L"; String v_s = "s"; String v_c = "c"; String v_guess = "X"; String v_id = "id"; String v_length_suffix = "_length"; int use_if_threshold = 3; int char_tail_test_threshold = 2; private IdValuePair[] pairs; private String default_value; private int[] columns; private boolean c_was_defined; private CodePrinter P; private ToolErrorReporter R; private String source_file; public CodePrinter getCodePrinter() { return P; } public void setCodePrinter(CodePrinter value) { P = value; } public ToolErrorReporter getReporter() { return R; } public void setReporter(ToolErrorReporter value) { R = value; } public String getSourceFileName() { return source_file; } public void setSourceFileName(String value) { source_file = value; } public void generateSwitch(String[] pairs, String default_value) { int N = pairs.length / 2; IdValuePair[] id_pairs = new IdValuePair[N]; for (int i = 0; i != N; ++i) { id_pairs[i] = new IdValuePair(pairs[2 * i], pairs[2 * i + 1]); } generateSwitch(id_pairs, default_value); } public void generateSwitch(IdValuePair[] pairs, String default_value) { int begin = 0; int end = pairs.length; if (begin == end) { return; } this.pairs = pairs; this.default_value = default_value; generate_body(begin, end, 2); } private void generate_body(int begin, int end, int indent_level) { P.indent(indent_level); P.p(v_switch_label); P.p(": { "); P.p(v_id); P.p(" = "); P.p(default_value); P.p("; String "); P.p(v_guess); P.p(" = null;"); c_was_defined = false; int c_def_begin = P.getOffset(); P.p(" int "); P.p(v_c); P.p(';'); int c_def_end = P.getOffset(); P.nl(); generate_length_switch(begin, end, indent_level + 1); if (!c_was_defined) { P.erase(c_def_begin, c_def_end); } P.indent(indent_level + 1); P.p("if ("); P.p(v_guess); P.p("!=null && "); P.p(v_guess); P.p("!="); P.p(v_s); P.p(" && !"); P.p(v_guess); P.p(".equals("); P.p(v_s); P.p(")) "); P.p(v_id); P.p(" = "); P.p(default_value); P.p(";"); P.nl(); P.line(indent_level, "}"); } private void generate_length_switch(int begin, int end, int indent_level) { sort_pairs(begin, end, -1); check_all_is_different(begin, end); int lengths_count = count_different_lengths(begin, end); columns = new int[pairs[end - 1].idLength]; boolean use_if; if (lengths_count <= use_if_threshold) { use_if = true; if (lengths_count != 1) { P.indent(indent_level); P.p("int "); P.p(v_s); P.p(v_length_suffix); P.p(" = "); P.p(v_s); P.p(".length();"); P.nl(); } } else { use_if = false; P.indent(indent_level); P.p(v_label); P.p(": switch ("); P.p(v_s); P.p(".length()) {"); P.nl(); } int same_length_begin = begin; int cur_l = pairs[begin].idLength, l = 0; for (int i = begin;;) { ++i; if (i == end || (l = pairs[i].idLength) != cur_l) { int next_indent; if (use_if) { P.indent(indent_level); if (same_length_begin != begin) { P.p("else "); } P.p("if ("); if (lengths_count == 1) { P.p(v_s); P.p(".length()=="); } else { P.p(v_s); P.p(v_length_suffix); P.p("=="); } P.p(cur_l); P.p(") {"); next_indent = indent_level + 1; } else { P.indent(indent_level); P.p("case "); P.p(cur_l); P.p(":"); next_indent = indent_level + 1; } generate_letter_switch (same_length_begin, i, next_indent, !use_if, use_if); if (use_if) { P.p("}"); P.nl(); } else { P.p("break "); P.p(v_label); P.p(";"); P.nl(); } if (i == end) { break; } same_length_begin = i; cur_l = l; } } if (!use_if) { P.indent(indent_level); P.p("}"); P.nl(); } } private void generate_letter_switch (int begin, int end, int indent_level, boolean label_was_defined, boolean inside_if) { int L = pairs[begin].idLength; for (int i = 0; i != L; ++i) { columns[i] = i; } generate_letter_switch_r (begin, end, L, indent_level, label_was_defined, inside_if); } private boolean generate_letter_switch_r (int begin, int end, int L, int indent_level, boolean label_was_defined, boolean inside_if) { boolean next_is_unreachable = false; if (begin + 1 == end) { P.p(' '); IdValuePair pair = pairs[begin]; if (L > char_tail_test_threshold) { P.p(v_guess); P.p("="); P.qstring(pair.id); P.p(";"); P.p(v_id); P.p("="); P.p(pair.value); P.p(";"); } else { if (L == 0) { next_is_unreachable = true; P.p(v_id); P.p("="); P.p(pair.value); P.p("; break "); P.p(v_switch_label); P.p(";"); } else { P.p("if ("); int column = columns[0]; P.p(v_s); P.p(".charAt("); P.p(column); P.p(")=="); P.qchar(pair.id.charAt(column)); for (int i = 1; i != L; ++i) { P.p(" && "); column = columns[i]; P.p(v_s); P.p(".charAt("); P.p(column); P.p(")=="); P.qchar(pair.id.charAt(column)); } P.p(") {"); P.p(v_id); P.p("="); P.p(pair.value); P.p("; break "); P.p(v_switch_label); P.p(";}"); } } P.p(' '); return next_is_unreachable; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -