| /* |
| * Copyright 2009 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.dev.jjs.impl; |
| |
| import com.google.gwt.core.ext.linker.StatementRanges; |
| import com.google.gwt.core.ext.linker.impl.StandardStatementRanges; |
| import com.google.gwt.dev.jjs.JsSourceMap; |
| |
| import java.util.ArrayList; |
| |
| /** |
| * Base class for transforming program text. |
| */ |
| public abstract class JsAbstractTextTransformer { |
| |
| protected String js; |
| |
| protected StatementRanges originalStatementRanges; |
| |
| protected StatementRanges statementRanges; |
| |
| protected JsSourceMap sourceInfoMap; |
| |
| public JsAbstractTextTransformer(JsAbstractTextTransformer xformer) { |
| this(xformer.getJs(), xformer.getStatementRanges(), xformer.getSourceInfoMap()); |
| } |
| |
| public JsAbstractTextTransformer(String js, StatementRanges statementRanges, |
| JsSourceMap sourceInfoMap) { |
| this.js = js; |
| this.statementRanges = statementRanges; |
| this.originalStatementRanges = statementRanges; |
| this.sourceInfoMap = sourceInfoMap; |
| } |
| |
| public abstract void exec(); |
| |
| public String getJs() { |
| return js; |
| } |
| |
| public JsSourceMap getSourceInfoMap() { |
| return sourceInfoMap; |
| } |
| |
| public StatementRanges getStatementRanges() { |
| return statementRanges; |
| } |
| |
| protected void addStatement(int index, String code, StringBuilder newJs, |
| ArrayList<Integer> starts, ArrayList<Integer> ends) { |
| beginStatement(index, newJs, starts); |
| newJs.append(code); |
| endStatement(index, newJs, ends); |
| } |
| |
| protected void beginStatement(int index, StringBuilder newJs, ArrayList<Integer> starts) { |
| starts.add(newJs.length()); |
| } |
| |
| /** |
| * Called if any operations need to be performed before all statements have |
| * been processed. |
| * |
| * @param newJs |
| * @param starts |
| * @param ends |
| */ |
| protected void beginStatements(StringBuilder newJs, ArrayList<Integer> starts, |
| ArrayList<Integer> ends) { |
| } |
| |
| protected void endStatement(int index, StringBuilder newJs, ArrayList<Integer> ends) { |
| ends.add(newJs.length()); |
| } |
| |
| /** |
| * Called if any operations need to be performed after all statements have |
| * been processed. |
| * |
| * @param newJs |
| * @param starts |
| * @param ends |
| */ |
| protected void endStatements(StringBuilder newJs, ArrayList<Integer> starts, |
| ArrayList<Integer> ends) { |
| } |
| |
| protected String getJsForRange(int stmtIndex) { |
| return js.substring(statementRanges.start(stmtIndex), statementRanges.end(stmtIndex)); |
| } |
| |
| /** |
| * Dump functions and fragments back into a new JS string, and calculate a new |
| * StatementRanges object. |
| */ |
| protected void recomputeJsAndStatementRanges(int[] stmtIndices) { |
| |
| StringBuilder newJs = new StringBuilder(); |
| ArrayList<Integer> starts = new ArrayList<Integer>(); |
| ArrayList<Integer> ends = new ArrayList<Integer>(); |
| |
| beginStatements(newJs, starts, ends); |
| for (int stmtIndex : stmtIndices) { |
| String code = getJsForRange(stmtIndex); |
| addStatement(stmtIndex, code, newJs, starts, ends); |
| } |
| endStatements(newJs, starts, ends); |
| |
| assert starts.size() == ends.size() : "Size mismatch between start and" |
| + " end statement ranges."; |
| assert starts.get(0) == 0 && ends.get(ends.size() - 1) == newJs.length() : |
| "statement ranges don't cover entire JS output string."; |
| |
| js = newJs.toString(); |
| statementRanges = new StandardStatementRanges(starts, ends); |
| updateSourceInfoMap(); |
| } |
| |
| /** |
| * Update the expression ranges in the SourceInfo map after the |
| * transformer has manipulated the statements. |
| */ |
| protected abstract void updateSourceInfoMap(); |
| |
| } |