package com.digiarea.closurefx.build; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import com.digiarea.closure.core.IPathResolver; import com.digiarea.closure.model.Buildpath; import com.digiarea.closure.model.Check; import com.digiarea.closure.model.CheckType; import com.digiarea.closure.model.Checks; import com.digiarea.closure.model.Closure; import com.digiarea.closure.model.ClosureGss; import com.digiarea.closure.model.ClosureJs; import com.digiarea.closure.model.ClosureSoy; import com.digiarea.closure.model.ExcludeInputFilter; import com.digiarea.closure.model.GssAtRule; import com.digiarea.closure.model.GssAtRules; import com.digiarea.closure.model.GssDefine; import com.digiarea.closure.model.GssDefines; import com.digiarea.closure.model.GssExcludedClass; import com.digiarea.closure.model.GssExcludedClasses; import com.digiarea.closure.model.GssInputOrientation; import com.digiarea.closure.model.GssNonStandardFunction; import com.digiarea.closure.model.GssNonStandardFunctions; import com.digiarea.closure.model.GssOptimizationLevel; import com.digiarea.closure.model.GssOutputFormat; import com.digiarea.closure.model.GssOutputOrientation; import com.digiarea.closure.model.GssOutputRenamingMapFormat; import com.digiarea.closure.model.GssRenamingType; import com.digiarea.closure.model.GssUnrecognizeProperties; import com.digiarea.closure.model.GssUnrecognizeProperty; import com.digiarea.closure.model.GssVendor; import com.digiarea.closure.model.IncludeInputFilter; import com.digiarea.closure.model.Info; import com.digiarea.closure.model.InputFilterPattern; import com.digiarea.closure.model.InputFilterType; import com.digiarea.closure.model.JsDefine; import com.digiarea.closure.model.JsDefineType; import com.digiarea.closure.model.JsDefines; import com.digiarea.closure.model.JsDoc; import com.digiarea.closure.model.JsDocs; import com.digiarea.closure.model.JsFunctionMap; import com.digiarea.closure.model.JsPropertyMap; import com.digiarea.closure.model.JsRenaming; import com.digiarea.closure.model.JsRenamingFunctionPolice; import com.digiarea.closure.model.JsRenamingPropertyPolice; import com.digiarea.closure.model.JsRenamingVariablePolice; import com.digiarea.closure.model.JsSourceMapFormat; import com.digiarea.closure.model.JsVariableMap; import com.digiarea.closure.model.LangType; import com.digiarea.closure.model.Language; import com.digiarea.closure.model.Optimization; import com.digiarea.closure.model.OptimizationType; import com.digiarea.closure.model.Optimizations; import com.digiarea.closure.model.Output; import com.digiarea.closure.model.SeverityType; import com.digiarea.closure.model.Source; import com.digiarea.closure.model.SourceEntity; import com.digiarea.closure.model.SourceEntry; import com.digiarea.closure.model.SoyCodeStyle; import com.digiarea.closure.model.SoyCssSchemeType; import com.digiarea.closure.model.SoyLocale; import com.digiarea.closure.model.SoyLocales; import com.digiarea.closure.model.Warning; import com.digiarea.closure.model.WarningType; import com.digiarea.closure.model.Warnings; import com.digiarea.closure.model.visitor.VoidVisitorAdapter; import com.google.common.css.JobDescription.InputOrientation; import com.google.common.css.JobDescription.OptimizeStrategy; import com.google.common.css.JobDescription.OutputFormat; import com.google.common.css.JobDescription.OutputOrientation; import com.google.common.css.JobDescriptionBuilder; import com.google.common.css.OutputRenamingMapFormat; import com.google.common.css.Vendor; import com.google.common.css.compiler.commandline.RenamingType; import com.google.javascript.jscomp.AnonymousFunctionNamingPolicy; import com.google.javascript.jscomp.CheckLevel; import com.google.javascript.jscomp.ClosureCodingConvention; import com.google.javascript.jscomp.CodingConvention; import com.google.javascript.jscomp.CodingConventions; import com.google.javascript.jscomp.CompilerOptions; import com.google.javascript.jscomp.CompilerOptions.LanguageMode; import com.google.javascript.jscomp.DependencyOptions; import com.google.javascript.jscomp.DiagnosticGroup; import com.google.javascript.jscomp.DiagnosticGroups; import com.google.javascript.jscomp.JqueryCodingConvention; import com.google.javascript.jscomp.PropertyRenamingPolicy; import com.google.javascript.jscomp.SourceMap; import com.google.javascript.jscomp.VariableMap; import com.google.javascript.jscomp.VariableRenamingPolicy; import com.google.javascript.jscomp.XtbMessageBundle; import com.google.template.soy.jssrc.SoyJsSrcOptions; import com.google.template.soy.jssrc.SoyJsSrcOptions.CodeStyle; /** * * Maps @see Closure model. * * @author daginno * */ public class Closurer extends VoidVisitorAdapter<Object> { @Override public void visit(Buildpath n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(Check n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getType() != null) { switch (n.getType()) { case CHAIN_CALLS: jsOptions.setChainCalls(n.isCheck()); break; // case CHECK_CAJA: // jsOptions.setCheckCaja(n.isCheck()); // break; // case CHECK_CONTROL_SCTRUCTURES: // jsOptions.setCheckControlStructures(n.isCheck()); // break; case CHECK_SUSPICIOUS_CODE: jsOptions.setCheckSuspiciousCode(n.isCheck()); break; case CHECK_SYMBOLS: jsOptions.setCheckSymbols(n.isCheck()); break; case CHECK_TYPES: jsOptions.setCheckTypes(n.isCheck()); break; case COMPUTE_FUNCTION_SIDE_EFFECTS: jsOptions.setComputeFunctionSideEffects(n.isCheck()); break; // case TIGHTEN_TYPES: // jsOptions.setTightenTypes(n.isCheck()); // break; } n.getType().accept(this, ctx); } } @Override public void visit(Checks n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(CheckType n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(Closure n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(ClosureGss n, Object ctx) throws Exception { super.visit(n, ctx); gssOptions.setAllowWebkitKeyframes(true); gssOptions.setEliminateDeadStyles(true); gssOptions.setProcessDependencies(true); gssOptions.setSimplifyCss(true); gssOptions.setAllowUnrecognizedFunctions(n .isAllowUnrecognizedFunctions()); gssOptions.setAllowUnrecognizedProperties(n .isAllowUnrecognizedProperties()); gssOptions.setCopyrightNotice(n.getCopyrightNotice()); String prefix = n.getCssRenamingPrefix(); if (prefix != null) { gssOptions.setCssRenamingPrefix(n.getCssRenamingPrefix()); } gssOptions.setOptimizeStrategy(OptimizeStrategy.SAFE); } @Override public void visit(ClosureJs n, Object ctx) throws Exception { // we manage optimization first because other options can modify // skipAllPasses to be evaluated // we skip all passes when it is true or checks is empty list if (!n.isDevmode() && n.isSkipAllPasses()) { jsOptions.setSkipAllPasses(n.isSkipAllPasses()); } else if (!n.isDevmode() && n.isFunctionsOnly()) { jsOptions.setNameAnonymousFunctionsOnly(n.isFunctionsOnly()); } else { if ((n.getChecks() == null || n.getChecks().getCheck().isEmpty() && (n.getOptimizations() == null || n.getOptimizations() .getOptimization().isEmpty()))) { jsOptions.setSkipAllPasses(true); } else { if (n.getChecks() != null) { n.getChecks().accept(this, ctx); } if (n.getOptimizations() != null) { n.getOptimizations().accept(this, ctx); } } } // we need to turn on checks if (n.isClosureStyle() || n.isClosurePass() || n.isJqueryPass()) { jsOptions.setSkipAllPasses(false); jsOptions.setNameAnonymousFunctionsOnly(false); } jsOptions.setAcceptConstKeyword(n.isAcceptConstKeyword()); jsOptions.setCodingConvention(mapCodeStyle(n.isClosureStyle(), n.isJqueryPass())); jsOptions.setInputDelimiter("//" + n.getInputDelimiter()); jsOptions.setLineBreak(n.isLineBreaksAggressive()); DependencyOptions dependencyOptions = new DependencyOptions(); dependencyOptions.setDependencySorting(true); dependencyOptions.setDependencyPruning(false); jsOptions.setDependencyOptions(dependencyOptions); jsOptions.setPreferLineBreakAtEndOfFile(n.isLineBreaks()); jsOptions.setPreferSingleQuotes(n.isSingleQuotes()); jsOptions.setPrettyPrint(n.isPrettyPrint()); jsOptions.setPrintInputDelimiter(n.isPrintInputDelimeter()); jsOptions.jqueryPass = n.isJqueryPass(); jsOptions.closurePass = n.isClosurePass(); jsOptions.setGenerateExports(n.isGenerateExports()); if (n.isExternExports()) { jsOptions.setExternExports(n.isExternExports()); jsOptions.setExternExportsPath(n.getExternExportsPath()); } if (n.getSourceMapFile() != null && !n.getSourceMapFile().isEmpty()) { jsOptions.setSourceMapOutputPath(pathResolver.toRealPath(n .getSourceMapFile())); } if (n.getCharset() != null && !n.getCharset().isEmpty()) { jsOptions.setOutputCharset(n.getCharset()); } if (n.getTranslationsFile() != null && !n.getTranslationsFile().isEmpty()) { try { jsOptions.setMessageBundle(new XtbMessageBundle( new FileInputStream(pathResolver.toRealPath(n .getTranslationsFile())), n .getTranslationsProject())); } catch (IOException e) { e.printStackTrace(); } } if (n.getInfo() != null) { n.getInfo().accept(this, ctx); } if (n.getBuildpath() != null) { n.getBuildpath().accept(this, ctx); } if (n.getOutput() != null) { n.getOutput().accept(this, ctx); } if (n.getWarnings() != null) { n.getWarnings().accept(this, ctx); } if (n.getJsDocs() != null) { n.getJsDocs().accept(this, ctx); } if (n.getLanguage() != null) { n.getLanguage().accept(this, ctx); } if (n.getJsDefines() != null) { n.getJsDefines().accept(this, ctx); } if (n.getRenaming() != null) { n.getRenaming().accept(this, ctx); } if (n.getSourceMapFormat() != null) { n.getSourceMapFormat().accept(this, ctx); } } private CodingConvention mapCodeStyle(boolean closurestyle, boolean jquery) { if (!closurestyle) { return CodingConventions.getDefault(); } else if (jquery) { return new JqueryCodingConvention(); } else { return new ClosureCodingConvention(); } } @Override public void visit(ClosureSoy n, Object ctx) throws Exception { super.visit(n, ctx); soyOptions.setGoogMsgsAreExternal(n.isGoogMessagesExternal()); soyOptions.setIsUsingIjData(n.isUsingIjData()); soyOptions.setShouldAllowDeprecatedSyntax(n.isAllowDeprecatedSyntax()); soyOptions.setShouldDeclareTopLevelNamespaces(n .isDeclareTopLevelNamespace()); soyOptions.setShouldGenerateGoogMsgDefs(n.isGenerateGoogMessagesDefs()); soyOptions.setShouldGenerateJsdoc(n.isGenerateJsDoc()); soyOptions.setShouldProvideRequireJsFunctions(n .isProvideRequireJsFunctions()); soyOptions.setShouldProvideRequireSoyNamespaces(n .isProvideRequireSoyNamespaces()); soyOptions.setUseGoogIsRtlForBidiGlobalDir(n.isRightToLeftDirGoog()); if (n.isRightToLeftDirGoog()) { soyOptions.setBidiGlobalDir(0); } else { soyOptions.setBidiGlobalDir(mapBigiGlobalDir(n.isRightToLeftDir())); } } private int mapBigiGlobalDir(boolean dir) { if (dir) { return -1; } else { return 1; } } @Override public void visit(ExcludeInputFilter n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(GssAtRule n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(GssAtRules n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(GssDefine n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(GssDefines n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getGssDefine() != null) { List<String> list = new ArrayList<String>(); for (GssDefine item : n.getGssDefine()) { if (item != null) { list.add(item.getValue()); } } gssOptions.setTrueConditionNames(list); } } @Override public void visit(GssExcludedClass n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(GssExcludedClasses n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getGssExcludedClass() != null) { List<String> clazzes = new ArrayList<String>(); for (GssExcludedClass item : n.getGssExcludedClass()) { if (item != null) { clazzes.add(item.getValue()); } } gssOptions.setExcludedClassesFromRenaming(clazzes); } } @Override public void visit(GssInputOrientation n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case DEFAULT: gssOptions.setInputOrientation(InputOrientation.LTR); break; case LTR: gssOptions.setInputOrientation(InputOrientation.LTR); break; case RTL: gssOptions.setInputOrientation(InputOrientation.RTL); break; } } @Override public void visit(GssNonStandardFunction n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(GssNonStandardFunctions n, Object ctx) throws Exception { super.visit(n, ctx); List<String> funcs = new ArrayList<String>(); if (n.getGssNonStandardFunction() != null) { for (GssNonStandardFunction item : n.getGssNonStandardFunction()) { if (item != null) { funcs.add(item.getValue()); } } } gssOptions.setAllowedNonStandardFunctions(funcs); } @Override public void visit(GssOptimizationLevel n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(GssOutputFormat n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case COMPRESSED: gssOptions.setOutputFormat(OutputFormat.COMPRESSED); break; case DEBUG: gssOptions.setOutputFormat(OutputFormat.DEBUG); break; case PRETTY_PRINTED: gssOptions.setOutputFormat(OutputFormat.PRETTY_PRINTED); break; } } @Override public void visit(GssOutputOrientation n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case DEFAULT: gssOptions.setOutputOrientation(OutputOrientation.LTR); break; case LTR: gssOptions.setOutputOrientation(OutputOrientation.LTR); break; case RTL: gssOptions.setOutputOrientation(OutputOrientation.RTL); break; case NOCHANGE: gssOptions.setOutputOrientation(OutputOrientation.NOCHANGE); break; } } @Override public void visit(GssOutputRenamingMapFormat n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case CLOSURE_COMPILED: gssOptions .setOutputRenamingMapFormat(OutputRenamingMapFormat.CLOSURE_COMPILED); break; case CLOSURE_COMPILED_SPLIT_HYPHENS: gssOptions .setOutputRenamingMapFormat(OutputRenamingMapFormat.CLOSURE_COMPILED_SPLIT_HYPHENS); break; case CLOSURE_UNCOMPILED: gssOptions .setOutputRenamingMapFormat(OutputRenamingMapFormat.CLOSURE_UNCOMPILED); break; case JSCOMP_VARIABLE_MAP: gssOptions .setOutputRenamingMapFormat(OutputRenamingMapFormat.JSCOMP_VARIABLE_MAP); break; case JSON: gssOptions.setOutputRenamingMapFormat(OutputRenamingMapFormat.JSON); break; case PROPERTIES: gssOptions .setOutputRenamingMapFormat(OutputRenamingMapFormat.PROPERTIES); break; } } @Override public void visit(GssRenamingType n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case CLOSURE: gssOptions.setCssSubstitutionMapProvider(RenamingType.CLOSURE .getCssSubstitutionMapProvider()); break; case DEBUG: gssOptions.setCssSubstitutionMapProvider(RenamingType.DEBUG .getCssSubstitutionMapProvider()); break; case NONE: gssOptions.setCssSubstitutionMapProvider(RenamingType.NONE .getCssSubstitutionMapProvider()); break; } } @Override public void visit(GssUnrecognizeProperties n, Object ctx) throws Exception { super.visit(n, ctx); List<String> props = new ArrayList<String>(); if (n.getGssUnrecognizeProperty() != null) { for (GssUnrecognizeProperty item : n.getGssUnrecognizeProperty()) { if (item != null) { props.add(item.getValue()); } } } gssOptions.setAllowedUnrecognizedProperties(props); } @Override public void visit(GssUnrecognizeProperty n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(GssVendor n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case KONQUEROR: gssOptions.setVendor(Vendor.KONQUEROR); break; case MICROSOFT: gssOptions.setVendor(Vendor.MICROSOFT); break; case MOZILLA: gssOptions.setVendor(Vendor.MOZILLA); break; case OPERA: gssOptions.setVendor(Vendor.OPERA); break; case WEBKIT: gssOptions.setVendor(Vendor.WEBKIT); break; case NONE: gssOptions.setVendor(null); break; } } @Override public void visit(IncludeInputFilter n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(Info n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(InputFilterPattern n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(InputFilterType n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(JsDefine n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getType() == JsDefineType.INT) { jsOptions.setDefineToNumberLiteral(n.getName(), Integer.parseInt(n.getValue())); } else if (n.getType() == JsDefineType.DOUBLE) { jsOptions.setDefineToDoubleLiteral(n.getName(), Float.parseFloat(n.getValue())); } else if (n.getType() == JsDefineType.BOOLEAN) { jsOptions.setDefineToBooleanLiteral(n.getName(), Boolean.parseBoolean(n.getValue())); } else if (n.getType() == JsDefineType.STRING) { jsOptions.setDefineToStringLiteral(n.getName(), n.getValue()); } } @Override public void visit(JsDefines n, Object ctx) throws Exception { // to enable defines, we need to activate passes!!! jsOptions.setSkipAllPasses(false); jsOptions.setNameAnonymousFunctionsOnly(false); super.visit(n, ctx); } @Override public void visit(JsDefineType n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(JsDoc n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(JsDocs n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getJsDoc() != null) { List<String> strings = new ArrayList<String>(); for (JsDoc item : n.getJsDoc()) { if (item != null) { strings.add(item.getValue()); } } jsOptions.setExtraAnnotationNames(new HashSet<String>(strings)); } } @Override public void visit(JsVariableMap n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getInput() != null && !n.getInput().isEmpty()) { String input = pathResolver.toRealPath(n.getInput()); jsOptions.setInputVariableMap(VariableMap.load(input)); } } @Override public void visit(JsFunctionMap n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getInput() != null && !n.getInput().isEmpty()) { String input = pathResolver.toRealPath(n.getInput()); jsOptions.setInputAnonymousFunctionNamingMap(VariableMap .load(input)); } } @Override public void visit(JsPropertyMap n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getInput() != null && !n.getInput().isEmpty()) { String input = pathResolver.toRealPath(n.getInput()); jsOptions.setInputPropertyMap(VariableMap.load(input)); } } @Override public void visit(JsRenaming n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getPrefix() != null && !n.getPrefix().isEmpty()) { jsOptions.setRenamePrefix(n.getPrefix()); } if (n.getPrefixNamespace() != null && !n.getPrefixNamespace().isEmpty()) { jsOptions.setRenamePrefixNamespace(n.getPrefixNamespace()); } jsOptions.setDevirtualizePrototypeMethods(n .isDevirtualizePrototypeMethods()); jsOptions.setGeneratePseudoNames(n.isGeneratePseudoNames()); jsOptions.setShadowVariables(n.isShadowVariables()); //jsOptions.setPropertyAffinity(n.isPropertyAffinity()); jsOptions.setDisambiguateProperties(n.isDisambiguateProperties()); jsOptions.setAmbiguateProperties(n.isAmbiguateProperties()); jsOptions.setExportTestFunctions(n.isExportTestFunctions()); jsOptions.setLabelRenaming(n.isRenameLabels()); // jsOptions.setRenamingPolicy(VariableRenamingPolicy.LOCAL, // PropertyRenamingPolicy.OFF); // ReplaceIdGenerators is on by default, but should run in simple mode. // jsOptions.setReplaceIdGenerators(false); // Does not call applyBasicCompilationOptions(options) because the call // to // skipAllCompilerPasses() cannot be easily undone. // jsOptions.closurePass = true; // jsOptions.setShadowVariables(true); // jsOptions.setInlineVariables(Reach.LOCAL_ONLY); // jsOptions.flowSensitiveInlineVariables = true; // jsOptions.setInlineFunctions(Reach.LOCAL_ONLY); // jsOptions.checkGlobalThisLevel = CheckLevel.OFF; // jsOptions.foldConstants = true; // jsOptions.coalesceVariableNames = true; // jsOptions.deadAssignmentElimination = true; // jsOptions.collapseVariableDeclarations = true; // jsOptions.convertToDottedProperties = true; // jsOptions.labelRenaming = true; // jsOptions.removeDeadCode = true; // jsOptions.optimizeArgumentsArray = true; // jsOptions.setRemoveUnusedVariables(Reach.LOCAL_ONLY); // jsOptions.setCollapseObjectLiterals(true); // jsOptions.setProtectHiddenSideEffects(true); } @Override public void visit(JsRenamingFunctionPolice n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case MAPPED: jsOptions .setAnonymousFunctionNaming(AnonymousFunctionNamingPolicy.MAPPED); break; case OFF: jsOptions .setAnonymousFunctionNaming(AnonymousFunctionNamingPolicy.OFF); break; case UNMAPPED: jsOptions .setAnonymousFunctionNaming(AnonymousFunctionNamingPolicy.UNMAPPED); break; } } @Override public void visit(JsRenamingPropertyPolice n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case AGGRESSIVE_HEURISTIC: jsOptions .setPropertyRenaming(PropertyRenamingPolicy.AGGRESSIVE_HEURISTIC); break; case ALL_UNQUOTED: jsOptions.setPropertyRenaming(PropertyRenamingPolicy.ALL_UNQUOTED); break; case HEURISTIC: jsOptions.setPropertyRenaming(PropertyRenamingPolicy.HEURISTIC); break; case OFF: jsOptions.setPropertyRenaming(PropertyRenamingPolicy.OFF); break; } } @Override public void visit(JsRenamingVariablePolice n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case ALL: jsOptions.setVariableRenaming(VariableRenamingPolicy.ALL); break; case LOCAL: jsOptions.setVariableRenaming(VariableRenamingPolicy.LOCAL); break; case OFF: jsOptions.setVariableRenaming(VariableRenamingPolicy.OFF); break; } } @Override public void visit(JsSourceMapFormat n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case V_3: jsOptions.setSourceMapFormat(SourceMap.Format.V3); break; case DEFAULT: default: jsOptions.setSourceMapFormat(SourceMap.Format.DEFAULT); break; } } @Override public void visit(LangType n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(Language n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getInput() != null) { jsOptions.setLanguageIn(mapLanguage(n.getInput())); } if (n.getOutput() != null) { jsOptions.setLanguageOut(mapLanguage(n.getOutput())); } } public static LanguageMode mapLanguage(LangType language) { switch (language) { case ECMASCRIPT_3: return LanguageMode.ECMASCRIPT3; case ECMASCRIPT_5: return LanguageMode.ECMASCRIPT5; case ECMASCRIPT_5_STRICT: return LanguageMode.ECMASCRIPT5_STRICT; default: return LanguageMode.ECMASCRIPT3; } } @Override public void visit(Optimization n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getType() != null) { switch (n.getType()) { case ALIAS_ALL_STRINGS: jsOptions.setAliasAllStrings(n.isOptimize()); break; case ALIAS_EXTERNALS: jsOptions.setAliasExternals(n.isOptimize()); break; // case ALIAS_KEYWORDS: // jsOptions.setAliasKeywords(n.isOptimize()); // break; case ASSUME_STRICT_THIS: jsOptions.setAssumeStrictThis(n.isOptimize()); break; case COALESCE_VARIABLE_NAMES: jsOptions.setCoalesceVariableNames(n.isOptimize()); break; case COLLAPSE_ANONYMOUS_FUNCTIONS: jsOptions.setCollapseAnonymousFunctions(n.isOptimize()); break; case COLLAPSE_OBJECT_LITERALS: jsOptions.setCollapseObjectLiterals(n.isOptimize()); break; case COLLAPSE_PROPERTIES: jsOptions.setCollapseProperties(n.isOptimize()); break; // case COLLAPSE_PROPERTIES_ON_EXTERN_TYPES: // jsOptions.setCollapsePropertiesOnExternTypes(n.isOptimize()); // break; case COLLAPSE_VARIABLE_DECLARATIONS: jsOptions.setCollapseVariableDeclarations(n.isOptimize()); break; case CONVERT_TO_DOTTED_PROPERTIES: jsOptions.setConvertToDottedProperties(n.isOptimize()); break; case CROSS_MODULE_CODE_MOTION: jsOptions.setCrossModuleCodeMotion(n.isOptimize()); break; case CROSS_MODULE_METHOD_MOTION: jsOptions.setCrossModuleMethodMotion(n.isOptimize()); break; case DEAD_ASSIGNMENT_ELIMINATION: jsOptions.setDeadAssignmentElimination(n.isOptimize()); break; case EXTRACT_PROTOTYPE_MEMBER_DECLARATION: jsOptions.setExtractPrototypeMemberDeclarations(n.isOptimize()); break; case FOLD_CONSTANTS: jsOptions.setFoldConstants(n.isOptimize()); break; case GROUP_VARIABLE_DECLARATIONS: jsOptions.setGroupVariableDeclarations(n.isOptimize()); break; case INLINE_CONSTANT_VAR: jsOptions.setInlineConstantVars(n.isOptimize()); break; case INLINE_FUNCTION: jsOptions.setInlineFunctions(n.isOptimize()); break; case INLINE_GETTERS: jsOptions.setInlineGetters(n.isOptimize()); break; case INLINE_LOCAL_FUNCTION: jsOptions.setInlineLocalFunctions(n.isOptimize()); break; case INLINE_LOCAL_VARIABLES: jsOptions.setInlineLocalVariables(n.isOptimize()); break; case INLINE_PROPERTIES: jsOptions.setInlineProperties(n.isOptimize()); break; case INLINE_VARIABLES: jsOptions.setInlineVariables(n.isOptimize()); break; case OPTIMIZE_PARAMETERS: jsOptions.setOptimizeParameters(n.isOptimize()); break; case OPTIMIZE_RETURNS: jsOptions.setOptimizeReturns(n.isOptimize()); break; case OUTPUT_JS_STRING_USAGE: jsOptions.setOutputJsStringUsage(n.isOptimize()); break; case REMOVE_DEAD_CODE: jsOptions.setRemoveDeadCode(n.isOptimize()); break; case REMOVE_UNUSED_CLASS_PROPERTIES: jsOptions.setRemoveUnusedClassProperties(n.isOptimize()); break; case REMOVE_UNUSED_LOCAL_VARS: jsOptions.setRemoveUnusedLocalVars(n.isOptimize()); break; case REMOVE_UNUSED_PROTOTYPE_PROPERTIES: jsOptions.setRemoveUnusedPrototypeProperties(n.isOptimize()); break; case REMOVE_UNUSED_PROTOTYPE_PROPERTIES_IN_EXTERNS: jsOptions.setRemoveUnusedPrototypePropertiesInExterns(n .isOptimize()); break; case REMOVE_UNUSED_VARS: jsOptions.setRemoveUnusedVars(n.isOptimize()); break; case REWRITE_FUNCTIONS_EXPRESSIONS: jsOptions.setRewriteFunctionExpressions(n.isOptimize()); break; case SMART_NAME_REMOVAL: jsOptions.setSmartNameRemoval(n.isOptimize()); break; case ASSUME_CLOSURES_ONLY_CAPTURE_PREFERENCES: break; case OPTIMIZE_ARGUMENTS_ARRAY: jsOptions.setOptimizeArgumentsArray(n.isOptimize()); break; case OPTIMIZE_CALLS: jsOptions.setOptimizeCalls(n.isOptimize()); break; } n.getType().accept(this, ctx); } } @Override public void visit(Optimizations n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(OptimizationType n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(Output n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(SeverityType n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(Source n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(SourceEntity n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(SourceEntry n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(SoyCodeStyle n, Object ctx) throws Exception { super.visit(n, ctx); switch (n) { case CONCAT: soyOptions.setCodeStyle(CodeStyle.CONCAT); break; case STRINGBUILDER: soyOptions.setCodeStyle(CodeStyle.STRINGBUILDER); break; } } @Override public void visit(SoyCssSchemeType n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(SoyLocale n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(SoyLocales n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(Warning n, Object ctx) throws Exception { super.visit(n, ctx); if (n.getSeverity() != null && n.getType() != null) { switch (n.getType()) { case AGGRESSIVE_VAR_CHECK: jsOptions .setAggressiveVarCheck(mapSeverityType(n.getSeverity())); break; case BROKEN_REQUIRES_LEVEL: jsOptions.setBrokenClosureRequiresLevel(mapSeverityType(n .getSeverity())); break; case CHECK_GLOBAL_NAMES_LEVEL: jsOptions.setCheckGlobalNamesLevel(mapSeverityType(n .getSeverity())); break; case CHECK_GLOBAL_THIS_LEVEL: jsOptions.setCheckGlobalThisLevel(mapSeverityType(n .getSeverity())); break; // case CHECK_MISSING_GET_CSS_NAME_LEVEL: // jsOptions.setCheckMissingGetCssNameLevel(mapSeverityType(n // .getSeverity())); // break; case CHECK_MISSING_RETURN: jsOptions .setCheckMissingReturn(mapSeverityType(n.getSeverity())); break; case CHECK_REQUIRES: jsOptions.setWarningLevel( DiagnosticGroups.MISSING_REQUIRE, mapSeverityType(n.getSeverity())); break; // case CHECK_UNREACHABLE_CODE: // jsOptions.setCheckUnreachableCode(mapSeverityType(n // .getSeverity())); // break; case REPORT_MISSING_OVERRIDE: jsOptions.setReportMissingOverride(mapSeverityType(n .getSeverity())); break; default: DiagnosticGroup group = mapWarningType(n.getType()); CheckLevel level = mapSeverityType(n.getSeverity()); if (group != null && level != null) { jsOptions.setWarningLevel(group, level); } break; } } if (n.getSeverity() != null) { n.getSeverity().accept(this, ctx); } if (n.getType() != null) { n.getType().accept(this, ctx); } } private DiagnosticGroup mapWarningType(WarningType warningType) { if (warningType != null) { switch (warningType) { case ACCESS_CONTROLS: return DiagnosticGroups.ACCESS_CONTROLS; case AMBIGUOUS_FUNCTION_DECL: return DiagnosticGroups.AMBIGUOUS_FUNCTION_DECL; case CHECK_PROVIDES: return DiagnosticGroups.MISSING_PROVIDE; case CHECK_REGEXP: return DiagnosticGroups.CHECK_REGEXP; case CHECK_TYPES: return DiagnosticGroups.CHECK_TYPES; case CHECK_VARS: return DiagnosticGroups.CHECK_VARIABLES; case CONST: return DiagnosticGroups.CONST; case CONSTANT_PROPERTY: return DiagnosticGroups.CONSTANT_PROPERTY; case DEBUGGER_STATEMENT_PRESENT: return DiagnosticGroups.DEBUGGER_STATEMENT_PRESENT; case DEPRECATED: return DiagnosticGroups.DEPRECATED; case ES_5_STRICT: return DiagnosticGroups.ES5_STRICT; case EXTERNS_VALIDATION: return DiagnosticGroups.EXTERNS_VALIDATION; case FILEOVERVIEW_JSDOC: return DiagnosticGroups.FILEOVERVIEW_JSDOC; case GLOBAL_THIS: return DiagnosticGroups.GLOBAL_THIS; case INTERNET_EXPLORER_CHECKS: return DiagnosticGroups.INTERNET_EXPLORER_CHECKS; case INVALID_CASTS: return DiagnosticGroups.INVALID_CASTS; case MISSING_PROPERTIES: return DiagnosticGroups.MISSING_PROPERTIES; case NON_STANDARD_JS_DOCS: return DiagnosticGroups.NON_STANDARD_JSDOC; case STRICT_MODULE_DEP_CHECK: return DiagnosticGroups.STRICT_MODULE_DEP_CHECK; case SUSPICIOUS_CODE: return DiagnosticGroups.SUSPICIOUS_CODE; case UNDEFINED_NAMES: return DiagnosticGroups.UNDEFINED_NAMES; case UNDEFINED_VARS: return DiagnosticGroups.UNDEFINED_VARIABLES; case UNKNOWN_DEFINES: return DiagnosticGroups.UNKNOWN_DEFINES; case CHECK_USELESS_CODE: return DiagnosticGroups.CHECK_USELESS_CODE; case VISIBILITY: return DiagnosticGroups.VISIBILITY; case CHECK_STRUCT_DICT_INHERITENCE: return DiagnosticGroups.CHECK_STRUCT_DICT_INHERITANCE; case DUPLICATE_MESSAGES: return DiagnosticGroups.DUPLICATE_MESSAGE; case DUPLICATE_VARS: return DiagnosticGroups.DUPLICATE_VARS; case MISPLACED_TYPE_ANNOTATION: return DiagnosticGroups.MISPLACED_TYPE_ANNOTATION; case TWEAKS: return DiagnosticGroups.TWEAKS; case TYPE_INVALIDATION: return DiagnosticGroups.TYPE_INVALIDATION; case VIOLATED_MODULE_DEP: return DiagnosticGroups.VIOLATED_MODULE_DEP; case REPORT_UNKNOWN_TYPES: return DiagnosticGroups.REPORT_UNKNOWN_TYPES; case AGGRESSIVE_VAR_CHECK: case BROKEN_REQUIRES_LEVEL: case CHECK_GLOBAL_NAMES_LEVEL: case CHECK_GLOBAL_THIS_LEVEL: // case CHECK_MISSING_GET_CSS_NAME_LEVEL: case CHECK_MISSING_RETURN: case CHECK_REQUIRES: case CHECK_UNREACHABLE_CODE: case REPORT_MISSING_OVERRIDE: // options are setted by separated methods break; case CHECK_EVENTFUL_OBJECT_DISPOSAL: return DiagnosticGroups.CHECK_EVENTFUL_OBJECT_DISPOSAL; case ES3: return DiagnosticGroups.ES3; case UNNECESSARY_CASTS: return DiagnosticGroups.UNNECESSARY_CASTS; default: break; } } return null; } private CheckLevel mapSeverityType(SeverityType severityType) { if (severityType != null) { switch (severityType) { case ERROR: return CheckLevel.ERROR; case OFF: return CheckLevel.OFF; case WARNING: return CheckLevel.WARNING; default: return CheckLevel.OFF; } } return null; } @Override public void visit(Warnings n, Object ctx) throws Exception { super.visit(n, ctx); } @Override public void visit(WarningType n, Object ctx) throws Exception { super.visit(n, ctx); } private IPathResolver pathResolver; private CompilerOptions jsOptions; private JobDescriptionBuilder gssOptions; private SoyJsSrcOptions soyOptions; public Closurer(IPathResolver pathResolver) { this(new CompilerOptions(), new JobDescriptionBuilder(), new SoyJsSrcOptions(), pathResolver); } public Closurer(CompilerOptions jsOptions, JobDescriptionBuilder gssOptions, SoyJsSrcOptions soyOptions, IPathResolver pathResolver) { this.jsOptions = jsOptions; this.gssOptions = gssOptions; this.soyOptions = soyOptions; this.pathResolver = pathResolver; } public CompilerOptions getJsOptions() { return jsOptions; } public SoyJsSrcOptions getSoyOptions() { return soyOptions; } public JobDescriptionBuilder getGssOptions() { return gssOptions; } }