taganalyzer.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 802 行 · 第 1/2 页
JAVA
802 行
*/ static class AbstractTagMethodAnalyzer extends Analyzer { private AnalyzedTag _tag; private boolean _hasCode; private int _count = 0; private int _value = -1; protected AbstractTagMethodAnalyzer(AnalyzedTag tag) { _tag = tag; } protected boolean hasCode() { return _hasCode; } protected void setHasCode() { _hasCode = true; } public void analyze(CodeVisitor visitor) { int count = _count++; switch (visitor.getOpcode()) { case CodeVisitor.IRETURN: if (count != 1) _hasCode = true; addReturnValue(_value); break; case CodeVisitor.ICONST_M1: case CodeVisitor.ICONST_0: case CodeVisitor.ICONST_1: case CodeVisitor.ICONST_2: case CodeVisitor.ICONST_3: case CodeVisitor.ICONST_4: case CodeVisitor.ICONST_5: if (count != 0) _hasCode = true; _value = visitor.getOpcode() - CodeVisitor.ICONST_0; break; case CodeVisitor.BIPUSH: if (count != 0) _hasCode = true; _value = visitor.getByteArg(); break; case CodeVisitor.SIPUSH: if (count != 0) _hasCode = true; _value = visitor.getShortArg(); break; case CodeVisitor.ALOAD_0: if (count != 0) _hasCode = true; break; case CodeVisitor.INVOKEVIRTUAL: case CodeVisitor.INVOKESPECIAL: { // matching int methods have an extra opcode for 'this' if (count != 1) _hasCode = true; _value = -1; int index = visitor.getShortArg(); JavaClass jClass = visitor.getJavaClass(); MethodRefConstant methodRef = jClass.getConstantPool().getMethodRef(index); IntMethodAnalyzer value = analyzeIntMethod(_tag, methodRef.getName(), methodRef.getType()); if (value != null) { _value = value.getValue(); // reset count since the subcall checks for side-effect code if (count == 1) _count = 1; if (value.hasCode()) { _hasCode = true; } } else { _hasCode = true; } } break; default: _hasCode = true; _value = -1; break; } } protected void addReturnValue(int value) { } } /** * Callback analyzing the doStartTag method. */ static class StartAnalyzer extends AbstractTagMethodAnalyzer { private boolean _hasSkip; private boolean _hasInclude; private boolean _hasBuffered; StartAnalyzer(AnalyzedTag tag) { super(tag); } @Override protected void addReturnValue(int value) { if (value == Tag.SKIP_BODY) _hasSkip = true; else if (value == Tag.EVAL_BODY_INCLUDE) _hasInclude = true; else if (value == BodyTag.EVAL_BODY_BUFFERED) _hasBuffered = true; else { _hasSkip = true; _hasInclude = true; _hasBuffered = true; setHasCode(); } } public void complete(AnalyzedTag tag) { tag.setDoStart(hasCode()); tag.setStartReturnsSkip(_hasSkip); tag.setStartReturnsInclude(_hasInclude); tag.setStartReturnsBuffered(_hasBuffered); } } /** * Callback analyzing the doEndTag method. */ static class EndAnalyzer extends AbstractTagMethodAnalyzer { private boolean _hasSkip; private boolean _hasEval; EndAnalyzer(AnalyzedTag tag) { super(tag); } @Override protected void addReturnValue(int value) { if (value == Tag.SKIP_PAGE) _hasSkip = true; else if (value == Tag.EVAL_PAGE) _hasEval = true; else { _hasSkip = true; _hasEval = true; setHasCode(); } } public void complete(AnalyzedTag tag) { tag.setDoEnd(hasCode()); tag.setEndReturnsSkip(_hasSkip); tag.setEndReturnsEval(_hasEval); } public String toString() { return (getClass().getSimpleName() + "[end:" + hasCode() + ",skip:" + _hasSkip + ",eval:" + _hasEval + "]"); } } /** * Callback analyzing the doAfterBody method. */ static class AfterAnalyzer extends AbstractTagMethodAnalyzer { private boolean _hasAgain; AfterAnalyzer(AnalyzedTag tag) { super(tag); } @Override protected void addReturnValue(int value) { if (value == IterationTag.EVAL_BODY_AGAIN) _hasAgain = true; else if (value == IterationTag.SKIP_BODY || value == BodyTag.SKIP_PAGE) { } else { _hasAgain = true; setHasCode(); } } public void complete(AnalyzedTag tag) { tag.setDoAfter(hasCode()); tag.setAfterReturnsAgain(_hasAgain); } } /** * Callback analyzing the doInitBody method. */ static class InitAnalyzer extends Analyzer { private boolean _hasCode; private int _count = 0; public void analyze(CodeVisitor visitor) { int count = _count++; switch (visitor.getOpcode()) { case CodeVisitor.RETURN: if (count != 0) _hasCode = true; break; default: _hasCode = true; break; } } public void complete(AnalyzedTag tag) { tag.setDoInit(_hasCode); } } /** * Callback analyzing the doCatch method. */ static class CatchAnalyzer extends Analyzer { private boolean _hasCode; private int _count = 0; public void analyze(CodeVisitor visitor) { int count = _count++; switch (visitor.getOpcode()) { case CodeVisitor.RETURN: if (count != 0) _hasCode = true; break; default: _hasCode = true; break; } } public void complete(AnalyzedTag tag) { tag.setDoCatch(_hasCode); } } /** * Callback analyzing the doFinally method. */ static class FinallyAnalyzer extends Analyzer { private boolean _hasCode; private int _count = 0; public void analyze(CodeVisitor visitor) { int count = _count++; switch (visitor.getOpcode()) { case CodeVisitor.RETURN: if (count != 0) _hasCode = true; break; default: _hasCode = true; break; } } public void complete(AnalyzedTag tag) { tag.setDoFinally(_hasCode); } } /** * Callback analyzing a zero-arg int method (for constant values). */ static class IntMethodAnalyzer extends Analyzer { private int _count = 0; private int _value = -1; private boolean _hasCode; private int _resultValue = -1; private int _resultValueCount = 0; public boolean isUnique() { return _resultValueCount == 1; } public boolean hasCode() { return _hasCode; } public int getValue() { return _resultValue; } public void analyze(CodeVisitor visitor) { int count = _count++; switch (visitor.getOpcode()) { case CodeVisitor.IRETURN: if (count > 1) _hasCode = true; if (_resultValueCount == 0) { _resultValue = _value; _resultValueCount = 1; } else if (_value != _resultValue) _resultValueCount++; break; case CodeVisitor.ICONST_M1: case CodeVisitor.ICONST_0: case CodeVisitor.ICONST_1: case CodeVisitor.ICONST_2: case CodeVisitor.ICONST_3: case CodeVisitor.ICONST_4: case CodeVisitor.ICONST_5: if (count > 0) _hasCode = true; _value = visitor.getOpcode() - CodeVisitor.ICONST_0; break; case CodeVisitor.BIPUSH: if (count > 0) _hasCode = true; _value = visitor.getByteArg(); break; case CodeVisitor.SIPUSH: if (count > 0) _hasCode = true; _value = visitor.getShortArg(); break; default: _hasCode = true; _value = -1; break; } } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?