/** * Runs middleend passes on the given Soy tree. * * @param soyTree The Soy tree to run middleend passes on. * @param doEnforceSyntaxVersionV2 Whether to enforce SyntaxVersion.V2. * @throws SoySyntaxException If a syntax error is found. * @throws SoyAutoescapeException If there is a problem determining the context for an {@code * autoescape="contextual"} template or one of its callers. */ private void runMiddleendPasses(SoyFileSetNode soyTree, boolean doEnforceSyntaxVersionV2) throws SoySyntaxException { // If diallowing external calls, perform the check. if (generalOptions.allowExternalCalls() == Boolean.FALSE) { (new AssertNoExternalCallsVisitor()).exec(soyTree); } // Handle CSS commands (if not backend-specific) and substitute compile-time globals. (new HandleCssCommandVisitor(generalOptions.getCssHandlingScheme())).exec(soyTree); if (generalOptions.getCompileTimeGlobals() != null) { (new SubstituteGlobalsVisitor(generalOptions.getCompileTimeGlobals(), false)).exec(soyTree); } // Soy version 1 allowed calling functions that are not backed by any SoyFunction definition. checkFunctionCallsVisitor.setAllowExternallyDefinedFunctions(!doEnforceSyntaxVersionV2); checkFunctionCallsVisitor.exec(soyTree); // Run contextual escaping after CSS has been done, but before the autoescape visitor adds // |escapeHtml directives. The contextual directive filterHtmlIdent serves the same purpose // in some places, but with runtime guarantees. doContextualEscaping(soyTree); performAutoescapeVisitor.exec(soyTree); // Attempt to simplify the tree. (new ChangeCallsToPassAllDataVisitor()).exec(soyTree); simplifyVisitor.exec(soyTree); }
/** * @param baseTofuFactory Factory for creating an instance of BaseTofu. * @param jsSrcMainProvider Provider for getting an instance of JsSrcMain. * @param javaSrcMainProvider Provider for getting an instance of JavaSrcMain. * @param performAutoescapeVisitor The instance of PerformAutoescapeVisitor to use. * @param contextualAutoescaper The instance of ContextualAutoescaper to use. * @param simplifyVisitor The instance of SimplifyVisitor to use. * @param soyFileSuppliers The suppliers for the input Soy files. * @param generalOptions The general compiler options. */ @Inject SoyFileSet( BaseTofuFactory baseTofuFactory, Provider<JsSrcMain> jsSrcMainProvider, Provider<JavaSrcMain> javaSrcMainProvider, Provider<GoSrcMain> goSrcMainProvider, PerformAutoescapeVisitor performAutoescapeVisitor, ContextualAutoescaper contextualAutoescaper, SimplifyVisitor simplifyVisitor, CheckFunctionCallsVisitor checkFunctionCallsVisitor, @Assisted List<SoyFileSupplier> soyFileSuppliers, @Assisted SoyGeneralOptions generalOptions) { // Default value is optionally replaced using method injection. this.msgBundleHandlerProvider = DEFAULT_SOY_MSG_BUNDLE_HANDLER_PROVIDER; this.baseTofuFactory = baseTofuFactory; this.jsSrcMainProvider = jsSrcMainProvider; this.javaSrcMainProvider = javaSrcMainProvider; this.goSrcMainProvider = goSrcMainProvider; this.performAutoescapeVisitor = performAutoescapeVisitor; this.contextualAutoescaper = contextualAutoescaper; this.simplifyVisitor = simplifyVisitor; this.checkFunctionCallsVisitor = checkFunctionCallsVisitor; Preconditions.checkArgument( soyFileSuppliers.size() > 0, "Must have non-zero number of input Soy files."); this.soyFileSuppliers = soyFileSuppliers; this.generalOptions = generalOptions.clone(); }
private List<Pair<String, String>> compileFileSetToGoSrc( SoyFileSetNode soyTree, SoyGoSrcOptions goSrcOptions, SoyMsgBundle msgBundle) { // Note: Globals should have been substituted already. The pass below is just a check. (new SubstituteGlobalsVisitor(generalOptions.getCompileTimeGlobals(), true)).exec(soyTree); return goSrcMainProvider.get().genGoSrc(soyTree, goSrcOptions, msgBundle); }
/** * Constructs a builder with a specified {@link SoyGeneralOptions} object. * * @param generalOptions The {@code SoyGeneralOptions} object to use. */ public Builder(SoyGeneralOptions generalOptions) { this.listBuilder = ImmutableList.builder(); this.generalOptions = generalOptions.clone(); // Bootstrap Guice for Soy API users that don't use Guice. This is done by statically // injecting an instance of SoyFileSetFactory into this Builder class. Everything derived // from this SoyFileSetFactory will be Guice-enabled. GuiceInitializer.initializeIfNecessary(); }
/** * Compiles this Soy file set into a Java object (type {@code SoyTofu}) capable of rendering the * compiled templates. * * @param tofuOptions The compilation options for the Tofu backend. * @return The resulting {@code SoyTofu} object. * @throws SoySyntaxException If a syntax error is found. */ public SoyTofu compileToTofu(SoyTofuOptions tofuOptions) throws SoySyntaxException { // Defensive copy of options. (Doesn't matter now, but might forget later when it matters.) tofuOptions = tofuOptions.clone(); // TODO: Allow binding a SoyTofu instance to volatile inputs. SoyFileSetNode soyTree = (new SoyFileSetParser(soyFileSuppliers)).parse(); runMiddleendPasses(soyTree, true); // If allowExternalCalls is not explicitly set, then disallow by default for Tofu backend. if (generalOptions.allowExternalCalls() == null) { // TODO: Enable this check when all Google internal projects are compliant. // (new AssertNoExternalCallsVisitor()).exec(soyTree); } // Note: Globals should have been substituted already. The pass below is just a check. (new SubstituteGlobalsVisitor(generalOptions.getCompileTimeGlobals(), true)).exec(soyTree); // Clear the SoyDoc strings because they use unnecessary memory. (new ClearSoyDocStringsVisitor()).exec(soyTree); return baseTofuFactory.create(soyTree, tofuOptions.useCaching()); }