📄 analyzer.java
字号:
/* * 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 Jamon code, released February, 2003. * * The Initial Developer of the Original Code is Jay Sachs. Portions * created by Jay Sachs are Copyright (C) 2003 Jay Sachs. All Rights * Reserved. * * Contributor(s): Ian Robertson */package org.jamon.codegen;import java.io.IOException;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.HashMap;import java.util.HashSet;import java.util.Set;import org.jamon.ParserError;import org.jamon.ParserErrors;import org.jamon.emit.EmitMode;import org.jamon.node.*;import org.jamon.util.StringUtils;public class Analyzer{ public Analyzer(String p_templatePath, TemplateDescriber p_describer, Set<String> p_children) throws IOException { m_templateUnit = new TemplateUnit(p_templatePath, m_errors); m_templateDir = p_templatePath.substring(0,1 + p_templatePath.lastIndexOf('/')); m_currentStatementBlock = m_templateUnit; m_describer = p_describer; m_children = p_children; m_emitMode = p_describer.getEmitMode(p_templatePath); m_templateIdentifier = m_describer.getExternalIdentifier(p_templatePath); m_templateUnit.setJamonContextType( p_describer.getJamonContextType(p_templatePath)); m_aliases.putAll(m_describer.getAliases(p_templatePath)); } public Analyzer(String p_templatePath, TemplateDescriber p_describer) throws IOException { this(p_templatePath, p_describer, new HashSet<String>()); } public TemplateUnit analyze() throws IOException { TopNode top = m_describer.parseTemplate(m_templateUnit.getName()); preAnalyze(top); mainAnalyze(top); checkForConcreteness(top); if (m_errors.hasErrors()) { throw m_errors; } return m_templateUnit; } private void addError(String p_message, Location p_location) { m_errors.addError(new ParserError(p_location, p_message)); } private void preAnalyze(TopNode p_top) { topLevelAnalyze(p_top, new AliasAdapter()); topLevelAnalyze(p_top, new PreliminaryAdapter()); if (m_defaultEscaping == null) { m_defaultEscaping = EscapingDirective.DEFAULT_ESCAPE_CODE; } } private void topLevelAnalyze(TopNode p_top, AnalysisAdapter p_adapter) { for (AbstractNode node : p_top.getSubNodes()) { node.apply(p_adapter); } } private void mainAnalyze(TopNode p_top) { p_top.apply(new Adapter()); } public void checkForConcreteness(TopNode p_top) { if (! getTemplateUnit().isParent() && ! getTemplateUnit().getAbstractMethodNames().isEmpty()) { topLevelAnalyze(p_top, new AnalysisAdapter() { @Override public void caseExtendsNode(ExtendsNode p_extends) { StringBuilder message = new StringBuilder("The abstract method(s) "); StringUtils.commaJoin(message, getTemplateUnit().getAbstractMethodNames() .iterator()); message.append(" have no concrete implementation"); addError(message.toString(), p_extends.getLocation()); } }); } } private void pushDefUnit(String p_defName) { m_currentStatementBlock = getTemplateUnit().getDefUnit(p_defName); } private void pushMethodUnit(String p_methodName) { m_currentStatementBlock = getTemplateUnit().getMethodUnit(p_methodName); } private void pushOverriddenMethodUnit(OverrideNode p_node) { m_currentStatementBlock = getTemplateUnit() .makeOverridenMethodUnit(p_node.getName(), p_node.getLocation()); } private void pushFlowControlBlock(Location p_location, String p_header) { FlowControlBlock flowControlBlock = new FlowControlBlock( m_currentStatementBlock, p_header, p_location); addStatement(flowControlBlock); m_currentStatementBlock = flowControlBlock; } private FragmentUnit pushFragmentUnitImpl(String p_fragName, Location p_location) { m_currentStatementBlock = new FragmentUnit( p_fragName, getCurrentStatementBlock(), getTemplateUnit().getGenericParams(), m_errors, p_location); return (FragmentUnit) m_currentStatementBlock; } private void pushFragmentArg(FragmentUnit p_frag) { m_currentStatementBlock = p_frag; } private void popStatementBlock() { m_currentStatementBlock = m_currentStatementBlock.getParent(); } private void pushCallStatement(CallStatement p_callStatement) { m_callStatements.add(p_callStatement); } private void popCallStatement() { m_callStatements.removeLast(); } private CallStatement getCurrentCallStatement() { return m_callStatements.getLast(); } private TemplateUnit getTemplateUnit() { return m_templateUnit; } private StatementBlock getCurrentStatementBlock() { return m_currentStatementBlock; } private final TemplateUnit m_templateUnit; private StatementBlock m_currentStatementBlock; private final TemplateDescriber m_describer; private final Set<String> m_children; private final LinkedList<CallStatement> m_callStatements = new LinkedList<CallStatement>(); private final Map<String, String> m_aliases = new HashMap<String, String>(); private final String m_templateDir; private final String m_templateIdentifier; private final EmitMode m_emitMode; private ParserErrors m_errors = new ParserErrors(); private String getAbsolutePath(String p_path) { return p_path.charAt(0) == '/' ? p_path : m_templateDir + p_path; } private String computePath(AbstractPathNode p_path) { PathAdapter adapter = new PathAdapter(m_templateDir, m_aliases, m_errors); p_path.apply(adapter); return adapter.getPath(); } private class AliasAdapter extends AnalysisAdapter { @Override public void caseAliasesNode(AliasesNode p_node) { for (AliasDefNode defNode : p_node.getAliass()) { handleAlias(defNode); } } private void handleAlias(AliasDefNode p_node) { if (m_aliases.containsKey(p_node.getName())) { addError("Duplicate alias for " + p_node.getName(), p_node.getLocation()); } else { m_aliases.put(p_node.getName(), computePath(p_node.getPath())); } } } private class PreliminaryAdapter extends AnalysisAdapter { @Override public void caseEscapeDirectiveNode(EscapeDirectiveNode p_escape) { if (m_defaultEscaping != null) { addError ("a template cannot specify multiple default escapings", p_escape.getLocation()); } m_defaultEscaping = p_escape.getEscapeCode(); if (EscapingDirective.get(m_defaultEscaping) == null) { addError("Unknown escaping directive '" + m_defaultEscaping + "'", p_escape.getLocation()); } } @Override public void caseExtendsNode(ExtendsNode p_extends) { if(getTemplateUnit().hasParentPath()) { addError ("a template cannot extend multiple templates", p_extends.getLocation()); } String parentPath = getAbsolutePath(computePath(p_extends.getPath())); getTemplateUnit().setParentPath(parentPath); if (m_children.contains(parentPath)) { addError( "cyclic inheritance involving " + parentPath, p_extends.getLocation()); } else { m_children.add(parentPath); try { getTemplateUnit().setParentDescription( m_describer.getTemplateDescription( parentPath, p_extends.getLocation(), m_templateIdentifier, m_children)); } catch (ParserError e) { m_errors.addError(e); } catch (ParserErrors e) { m_errors.addErrors(e); } catch (IOException e) { addError(e.getMessage(), p_extends.getLocation()); } } } @Override public void caseAnnotationNode(AnnotationNode p_node) { m_templateUnit.addAnnotationNode(p_node); } @Override public void caseParentMarkerNode(ParentMarkerNode p_node) { getTemplateUnit().setIsParent(); } @Override public void caseDefNode(DefNode p_node) { getTemplateUnit() .makeDefUnit(p_node.getName(), p_node.getLocation()); } @Override public void caseMethodNode(MethodNode p_node) { getTemplateUnit() .makeMethodUnit(p_node.getName(), p_node.getLocation(), false); } @Override public void caseAbsMethodNode(AbsMethodNode p_node) { getTemplateUnit().makeMethodUnit( p_node.getName(), p_node.getLocation(), true); } } private class Adapter extends DepthFirstAnalysisAdapter { @Override public void caseImportNode(ImportNode p_import) { getTemplateUnit().addImport(p_import); } @Override public void caseStaticImportNode(StaticImportNode p_import) { getTemplateUnit().addStaticImport(p_import); } @Override public void caseImplementNode(ImplementNode p_node) { getTemplateUnit().addInterface(p_node.getName()); } @Override public void caseParentArgsNode(ParentArgsNode p_node) { if (getCurrentStatementBlock() instanceof TemplateUnit && ! ((TemplateUnit) getCurrentStatementBlock()).hasParentPath()) { addError( "xargs may not be declared without extending another template", p_node.getLocation()); } else { super.caseParentArgsNode(p_node); } } @Override public void caseParentArgNode(ParentArgNode p_node) { ((InheritedUnit) getCurrentStatementBlock()).addParentArg(p_node); } @Override public void caseParentArgWithDefaultNode( ParentArgWithDefaultNode p_node) { ((InheritedUnit) getCurrentStatementBlock()).addParentArg(p_node); } @Override public void inFragmentArgsNode(FragmentArgsNode p_node) { pushFragmentArg(getCurrentStatementBlock().addFragment( p_node, getTemplateUnit().getGenericParams()));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -