lint

16:38:52.311 INFO  jd.cli.Main - Decompiling lint.jar
package com.android.tools.lint;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.Location.Handle;
import java.io.File;
import lombok.ast.Node;
import lombok.ast.Position;

class EcjParser$LocationHandle
  implements Location.Handle
{
  private File mFile;
  private Node mNode;
  private Object mClientData;
  
  public EcjParser$LocationHandle(File file, Node node)
  {
    mFile = file;
    mNode = node;
  }
  
  @NonNull
  public Location resolve()
  {
    Position pos = mNode.getPosition();
    return Location.create(mFile, null, pos.getStart(), pos.getEnd());
  }
  
  public void setClientData(@Nullable Object clientData)
  {
    mClientData = clientData;
  }
  
  @Nullable
  public Object getClientData()
  {
    return mClientData;
  }
}

/* Location:
 * Qualified Name:     com.android.tools.lint.EcjParser.LocationHandle
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.tools.lint;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.lint.client.api.IJavaParser;
import com.android.tools.lint.client.api.LintClient;
import com.android.tools.lint.detector.api.JavaContext;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.Location.Handle;
import java.io.File;
import java.util.List;
import lombok.ast.Node;
import lombok.ast.Position;
import lombok.ast.TypeReference;
import lombok.ast.ecj.EcjTreeConverter;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;

public class EcjParser
  implements IJavaParser
{
  private final Parser mParser;
  private final LintClient mClient;
  
  public EcjParser(LintClient client)
  {
    mClient = client;
    CompilerOptions options = new CompilerOptions();
    
    complianceLevel = 3342336L;
    sourceLevel = 3342336L;
    targetJDK = 3342336L;
    parseLiteralExpressionsAsConstants = true;
    ProblemReporter problemReporter = new ProblemReporter(DefaultErrorHandlingPolicies.exitOnFirstError(), options, new DefaultProblemFactory());
    
    mParser = new Parser(problemReporter, parseLiteralExpressionsAsConstants);
    mParser.javadocParser.checkDocComment = false;
  }
  
  public Node parseJava(@NonNull JavaContext context)
  {
    EcjTreeConverter converter = new EcjTreeConverter();
    String code = context.getContents();
    if (code == null) {
      return null;
    }
    org.eclipse.jdt.internal.compiler.batch.CompilationUnit sourceUnit = new org.eclipse.jdt.internal.compiler.batch.CompilationUnit(code.toCharArray(), file.getName(), "UTF-8");
    
    CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, 0);
    CompilationUnitDeclaration unit;
    try
    {
      unit = mParser.parse(sourceUnit, compilationResult);
    }
    catch (AbortCompilation e)
    {
      return null;
    }
    if (unit == null) {
      return null;
    }
    try
    {
      converter.visit(code, unit);
      List<? extends Node> nodes = converter.getAll();
      for (Node node : nodes) {
        if ((node instanceof lombok.ast.CompilationUnit)) {
          return node;
        }
      }
      return null;
    }
    catch (Throwable t)
    {
      mClient.log(t, "Failed converting ECJ parse tree to Lombok for file %1$s", new Object[] { file.getPath() });
    }
    return null;
  }
  
  @NonNull
  public Location getLocation(@NonNull JavaContext context, @NonNull Node node)
  {
    Position position = node.getPosition();
    return Location.create(file, context.getContents(), position.getStart(), position.getEnd());
  }
  
  @NonNull
  public Location.Handle createLocationHandle(@NonNull JavaContext context, @NonNull Node node)
  {
    return new LocationHandle(file, node);
  }
  
  public void dispose(@NonNull JavaContext context, @NonNull Node compilationUnit) {}
  
  @Nullable
  public Node resolve(@NonNull JavaContext context, @NonNull Node node)
  {
    return null;
  }
  
  @Nullable
  public TypeReference getType(@NonNull JavaContext context, @NonNull Node node)
  {
    return null;
  }
  
  private static class LocationHandle
    implements Location.Handle
  {
    private File mFile;
    private Node mNode;
    private Object mClientData;
    
    public LocationHandle(File file, Node node)
    {
      mFile = file;
      mNode = node;
    }
    
    @NonNull
    public Location resolve()
    {
      Position pos = mNode.getPosition();
      return Location.create(mFile, null, pos.getStart(), pos.getEnd());
    }
    
    public void setClientData(@Nullable Object clientData)
    {
      mClientData = clientData;
    }
    
    @Nullable
    public Object getClientData()
    {
      return mClientData;
    }
  }
}

/* Location:
 * Qualified Name:     com.android.tools.lint.EcjParser
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.tools.lint;

import java.util.Comparator;

class HtmlReporter$1
  implements Comparator<String>
{
  HtmlReporter$1(HtmlReporter paramHtmlReporter) {}
  
  public int compare(String s1, String s2)
  {
    return HtmlReporter.access$000(s1) - HtmlReporter.access$000(s2);
  }
}

/* Location:
 * Qualified Name:     com.android.tools.lint.HtmlReporter.1
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.tools.lint;

import com.android.tools.lint.checks.BuiltinIssueRegistry;
import com.android.tools.lint.client.api.Configuration;
import com.android.tools.lint.client.api.IssueRegistry;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.Issue.OutputFormat;
import com.android.tools.lint.detector.api.LintUtils;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.Position;
import com.android.tools.lint.detector.api.Project;
import com.android.tools.lint.detector.api.Severity;
import com.google.common.annotations.Beta;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
import com.google.common.io.Files;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Beta
public class HtmlReporter
  extends Reporter
{
  private static final boolean USE_HOLO_STYLE = true;
  private static final String CSS = "hololike.css";
  private static final int SPLIT_LIMIT = 8;
  private static final int SHOWN_COUNT = 5;
  protected final Writer mWriter;
  private String mStripPrefix;
  private String mFixUrl;
  
  public HtmlReporter(LintCliClient client, File output)
    throws IOException
  {
    super(client, output);
    mWriter = new BufferedWriter(Files.newWriter(output, Charsets.UTF_8));
  }
  
  public void write(int errorCount, int warningCount, List<Warning> issues)
    throws IOException
  {
    Map<Issue, String> missing = computeMissingIssues(issues);
    
    mWriter.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><title>" + mTitle + "</title>\n");
    
    writeStyleSheet();
    if (!mSimpleFormat) {
      mWriter.write("<script language=\"javascript\" type=\"text/javascript\"> \n<!--\nfunction reveal(id) {\nif (document.getElementById) {\ndocument.getElementById(id).style.display = 'block';\ndocument.getElementById(id+'Link').style.display = 'none';\n}\n}\n//--> \n</script>\n");
    }
    mWriter.write("</head>\n<body>\n<h1>" + mTitle + "</h1>\n" + "<div class=\"titleSeparator\"></div>\n");
    
    mWriter.write(String.format("Check performed at %1$s.", new Object[] { new Date().toString() }));
    
    mWriter.write("<br/>\n");
    mWriter.write(String.format("%1$d errors and %2$d warnings found:", new Object[] { Integer.valueOf(errorCount), Integer.valueOf(warningCount) }));
    
    mWriter.write("<br/><br/>\n");
    
    Issue previousIssue = null;
    if (!issues.isEmpty())
    {
      List<List<Warning>> related = new ArrayList();
      List<Warning> currentList = null;
      for (Warning warning : issues)
      {
        if (issue != previousIssue)
        {
          previousIssue = issue;
          currentList = new ArrayList();
          related.add(currentList);
        }
        assert (currentList != null);
        currentList.add(warning);
      }
      writeOverview(related, missing.size());
      
      Category previousCategory = null;
      for (List<Warning> warnings : related)
      {
        Warning first = (Warning)warnings.get(0);
        Issue issue = issue;
        if (issue.getCategory() != previousCategory)
        {
          previousCategory = issue.getCategory();
          mWriter.write("\n<a name=\"");
          mWriter.write(issue.getCategory().getFullName());
          mWriter.write("\"></a>\n");
          mWriter.write("<div class=\"category\"><a href=\"#\" title=\"Return to top\">");
          mWriter.write(issue.getCategory().getFullName());
          mWriter.write("</a><div class=\"categorySeparator\"></div>\n");
          mWriter.write("</div>\n");
        }
        mWriter.write("<a name=\"" + issue.getId() + "\"></a>\n");
        mWriter.write("<div class=\"issue\">\n");
        
        mWriter.write("<div class=\"id\"><a href=\"#\" title=\"Return to top\">");
        mWriter.write(issue.getId());
        mWriter.write(": ");
        mWriter.write(issue.getBriefDescription(Issue.OutputFormat.HTML));
        mWriter.write("</a><div class=\"issueSeparator\"></div>\n");
        mWriter.write("</div>\n");
        
        mWriter.write("<div class=\"warningslist\">\n");
        boolean partialHide = (!mSimpleFormat) && (warnings.size() > 8);
        
        int count = 0;
        for (Warning warning : warnings)
        {
          if ((partialHide) && (count == 5))
          {
            String id = issue.getId() + "Div";
            mWriter.write("<button id=\"");
            mWriter.write(id);
            mWriter.write("Link\" onclick=\"reveal('");
            mWriter.write(id);
            mWriter.write("');\" />");
            mWriter.write(String.format("+ %1$d More Occurrences...", new Object[] { Integer.valueOf(warnings.size() - 5) }));
            
            mWriter.write("</button>\n");
            mWriter.write("<div id=\"");
            mWriter.write(id);
            mWriter.write("\" style=\"display: none\">\n");
          }
          count++;
          String url = null;
          if (path != null)
          {
            url = writeLocation(file, path, line);
            mWriter.write(58);
            mWriter.write(32);
          }
          boolean addedImage = false;
          if ((url != null) && (location != null) && (location.getSecondary() == null)) {
            addedImage = addImage(url, location);
          }
          mWriter.write("<span class=\"message\">");
          appendEscapedText(message);
          mWriter.write("</span>");
          if (addedImage) {
            mWriter.write("<br clear=\"right\"/>");
          } else {
            mWriter.write("<br />");
          }
          if ((line >= 0) && (fileContents != null))
          {
            mWriter.write("<pre class=\"errorlines\">\n");
            appendCodeBlock(fileContents, line, offset);
            mWriter.write("\n</pre>");
          }
          mWriter.write(10);
          if ((location != null) && (location.getSecondary() != null))
          {
            mWriter.write("<ul>");
            Location l = location.getSecondary();
            int otherLocations = 0;
            while (l != null)
            {
              String message = l.getMessage();
              if ((message != null) && (!message.isEmpty()))
              {
                Position start = l.getStart();
                int line = start != null ? start.getLine() : -1;
                String path = mClient.getDisplayPath(project, l.getFile());
                writeLocation(l.getFile(), path, line);
                mWriter.write(58);
                mWriter.write(32);
                mWriter.write("<span class=\"message\">");
                appendEscapedText(message);
                mWriter.write("</span>");
                mWriter.write("<br />");
                
                String name = l.getFile().getName();
                if ((!LintUtils.endsWith(name, ".png")) && (!LintUtils.endsWith(name, ".jpg")))
                {
                  String s = mClient.readFile(l.getFile());
                  if ((s != null) && (!s.isEmpty()))
                  {
                    mWriter.write("<pre class=\"errorlines\">\n");
                    int offset = start != null ? start.getOffset() : -1;
                    appendCodeBlock(s, line, offset);
                    mWriter.write("\n</pre>");
                  }
                }
              }
              else
              {
                otherLocations++;
              }
              l = l.getSecondary();
            }
            mWriter.write("</ul>");
            if (otherLocations > 0)
            {
              String id = "Location" + count + "Div";
              mWriter.write("<button id=\"");
              mWriter.write(id);
              mWriter.write("Link\" onclick=\"reveal('");
              mWriter.write(id);
              mWriter.write("');\" />");
              mWriter.write(String.format("+ %1$d Additional Locations...", new Object[] { Integer.valueOf(otherLocations) }));
              
              mWriter.write("</button>\n");
              mWriter.write("<div id=\"");
              mWriter.write(id);
              mWriter.write("\" style=\"display: none\">\n");
              
              mWriter.write("Additional locations: ");
              mWriter.write("<ul>\n");
              l = location.getSecondary();
              while (l != null)
              {
                Position start = l.getStart();
                int line = start != null ? start.getLine() : -1;
                String path = mClient.getDisplayPath(project, l.getFile());
                mWriter.write("<li> ");
                writeLocation(l.getFile(), path, line);
                mWriter.write("\n");
                l = l.getSecondary();
              }
              mWriter.write("</ul>\n");
              
              mWriter.write("</div><br/><br/>\n");
            }
          }
          if ((!addedImage) && (url != null) && (location != null) && (location.getSecondary() != null)) {
            addImage(url, location);
          }
          if (warning.isVariantSpecific())
          {
            mWriter.write("\n");
            mWriter.write("Applies to variants: ");
            mWriter.write(Joiner.on(", ").join(warning.getIncludedVariantNames()));
            mWriter.write("<br/>\n");
            mWriter.write("Does <b>not</b> apply to variants: ");
            mWriter.write(Joiner.on(", ").join(warning.getExcludedVariantNames()));
            mWriter.write("<br/>\n");
          }
        }
        if (partialHide) {
          mWriter.write("</div>\n");
        }
        mWriter.write("</div>\n");
        writeIssueMetadata(issue, severity, null);
        
        mWriter.write("</div>\n");
      }
      if (!mClient.isCheckingSpecificIssues()) {
        writeMissingIssues(missing);
      }
      writeSuppressInfo();
    }
    else
    {
      mWriter.write("Congratulations!");
    }
    mWriter.write("\n</body>\n</html>");
    mWriter.close();
    
    String path = mOutput.getAbsolutePath();
    System.out.println(String.format("Wrote HTML report to %1$s", new Object[] { path }));
  }
  
  private void writeIssueMetadata(Issue issue, Severity severity, String disabledBy)
    throws IOException
  {
    mWriter.write("<div class=\"metadata\">");
    if (((mClient.getRegistry() instanceof BuiltinIssueRegistry)) && (((BuiltinIssueRegistry)mClient.getRegistry()).hasAutoFix("adt", issue)))
    {
      mWriter.write("Note: This issue has an associated quickfix operation in Eclipse/ADT");
      if (mFixUrl != null)
      {
        mWriter.write("&nbsp;<img alt=\"Fix\" border=\"0\" align=\"top\" src=\"");
        mWriter.write(mFixUrl);
        mWriter.write("\" />\n");
      }
      mWriter.write("<br>\n");
    }
    if (disabledBy != null) {
      mWriter.write(String.format("Disabled By: %1$s<br/>\n", new Object[] { disabledBy }));
    }
    mWriter.write("Priority: ");
    mWriter.write(String.format("%1$d / 10", new Object[] { Integer.valueOf(issue.getPriority()) }));
    mWriter.write("<br/>\n");
    mWriter.write("Category: ");
    mWriter.write(issue.getCategory().getFullName());
    mWriter.write("</div>\n");
    
    mWriter.write("Severity: ");
    if ((severity == Severity.ERROR) || (severity == Severity.FATAL)) {
      mWriter.write("<span class=\"error\">");
    } else if (severity == Severity.WARNING) {
      mWriter.write("<span class=\"warning\">");
    } else {
      mWriter.write("<span>");
    }
    appendEscapedText(severity.getDescription());
    mWriter.write("</span>");
    
    mWriter.write("<div class=\"summary\">\n");
    mWriter.write("Explanation: ");
    String description = issue.getDescription(Issue.OutputFormat.HTML);
    mWriter.write(description);
    if ((!description.isEmpty()) && (Character.isLetter(description.charAt(description.length() - 1)))) {
      mWriter.write(46);
    }
    mWriter.write("</div>\n");
    mWriter.write("<div class=\"explanation\">\n");
    String explanationHtml = issue.getExplanation(Issue.OutputFormat.HTML);
    mWriter.write(explanationHtml);
    mWriter.write("\n</div>\n");
    List<String> moreInfo = issue.getMoreInfo();
    mWriter.write("<br/>");
    mWriter.write("<div class=\"moreinfo\">");
    mWriter.write("More info: ");
    int count = moreInfo.size();
    if (count > 1) {
      mWriter.write("<ul>");
    }
    for (String uri : moreInfo)
    {
      if (count > 1) {
        mWriter.write("<li>");
      }
      mWriter.write("<a href=\"");
      mWriter.write(uri);
      mWriter.write("\">");
      mWriter.write(uri);
      mWriter.write("</a>\n");
    }
    if (count > 1) {
      mWriter.write("</ul>");
    }
    mWriter.write("</div>");
    
    mWriter.write("<br/>");
    mWriter.write(String.format("To suppress this error, use the issue id \"%1$s\" as explained in the %2$sSuppressing Warnings and Errors%3$s section.", new Object[] { issue.getId(), "<a href=\"#SuppressInfo\">", "</a>" }));
    
    mWriter.write("<br/>\n");
  }
  
  private void writeSuppressInfo()
    throws IOException
  {
    mWriter.write("\n<a name=\"SuppressInfo\"></a>\n");
    mWriter.write("<div class=\"category\">");
    mWriter.write("Suppressing Warnings and Errors");
    mWriter.write("<div class=\"categorySeparator\"></div>\n");
    mWriter.write("</div>\n");
    appendEscapedText(Main.getSuppressHelp());
    mWriter.write(10);
  }
  
  protected Map<Issue, String> computeMissingIssues(List<Warning> warnings)
  {
    Set<Project> projects = new HashSet();
    Set<Issue> seen = new HashSet();
    for (Warning warning : warnings)
    {
      projects.add(project);
      seen.add(issue);
    }
    Configuration cliConfiguration = mClient.getConfiguration();
    Map<Issue, String> map = Maps.newHashMap();
    for (Iterator i$ = mClient.getRegistry().getIssues().iterator(); i$.hasNext();)
    {
      issue = (Issue)i$.next();
      if (!seen.contains(issue)) {
        if (mClient.isSuppressed(issue)) {
          map.put(issue, "Command line flag");
        } else if ((!issue.isEnabledByDefault()) && (!mClient.isAllEnabled())) {
          map.put(issue, "Default");
        } else if ((cliConfiguration != null) && (!cliConfiguration.isEnabled(issue))) {
          map.put(issue, "Command line supplied --config lint.xml file");
        } else {
          for (Project project : projects) {
            if (!project.getConfiguration().isEnabled(issue))
            {
              map.put(issue, "Project lint.xml file");
              break;
            }
          }
        }
      }
    }
    Issue issue;
    return map;
  }
  
  private void writeMissingIssues(Map<Issue, String> missing)
    throws IOException
  {
    mWriter.write("\n<a name=\"MissingIssues\"></a>\n");
    mWriter.write("<div class=\"category\">");
    mWriter.write("Disabled Checks");
    mWriter.write("<div class=\"categorySeparator\"></div>\n");
    mWriter.write("</div>\n");
    
    mWriter.write("The following issues were not run by lint, either because the check is not enabled by default, or because it was disabled with a command line flag or via one or more lint.xml configuration files in the project directories.");
    
    mWriter.write("\n<br/><br/>\n");
    
    List<Issue> list = new ArrayList(missing.keySet());
    Collections.sort(list);
    for (Issue issue : list)
    {
      mWriter.write("<a name=\"" + issue.getId() + "\"></a>\n");
      mWriter.write("<div class=\"issue\">\n");
      
      mWriter.write("<div class=\"id\">");
      mWriter.write(issue.getId());
      mWriter.write("<div class=\"issueSeparator\"></div>\n");
      mWriter.write("</div>\n");
      String disabledBy = (String)missing.get(issue);
      writeIssueMetadata(issue, issue.getDefaultSeverity(), disabledBy);
      mWriter.write("</div>\n");
    }
  }
  
  protected void writeStyleSheet()
    throws IOException
  {
    mWriter.write("<link rel=\"stylesheet\" type=\"text/css\" href=\"http://fonts.googleapis.com/css?family=Roboto\" />\n");
    
    URL cssUrl = HtmlReporter.class.getResource("hololike.css");
    if (mSimpleFormat)
    {
      mWriter.write("<style>\n");
      
      InputStream input = cssUrl.openStream();
      byte[] bytes = ByteStreams.toByteArray(input);
      Closeables.closeQuietly(input);
      String css = new String(bytes, Charsets.UTF_8);
      mWriter.write(css);
      mWriter.write("</style>\n");
    }
    else
    {
      String ref = addLocalResources(cssUrl);
      if (ref != null) {
        mWriter.write("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + ref + "\" />\n");
      }
    }
  }
  
  private void writeOverview(List<List<Warning>> related, int missingCount)
    throws IOException
  {
    mWriter.write("<table class=\"overview\">\n");
    
    String errorUrl = null;
    String warningUrl = null;
    if (!mSimpleFormat)
    {
      errorUrl = addLocalResources(getErrorIconUrl());
      warningUrl = addLocalResources(getWarningIconUrl());
      mFixUrl = addLocalResources(HtmlReporter.class.getResource("lint-run.png"));
    }
    Category previousCategory = null;
    for (List<Warning> warnings : related)
    {
      Issue issue = get0issue;
      
      boolean isError = false;
      for (Warning warning : warnings) {
        if ((severity == Severity.ERROR) || (severity == Severity.FATAL))
        {
          isError = true;
          break;
        }
      }
      if (issue.getCategory() != previousCategory)
      {
        mWriter.write("<tr><td></td><td class=\"categoryColumn\">");
        previousCategory = issue.getCategory();
        String categoryName = issue.getCategory().getFullName();
        mWriter.write("<a href=\"#");
        mWriter.write(categoryName);
        mWriter.write("\">");
        mWriter.write(categoryName);
        mWriter.write("</a>\n");
        mWriter.write("</td></tr>");
        mWriter.write("\n");
      }
      mWriter.write("<tr>\n");
      
      mWriter.write("<td class=\"countColumn\">");
      mWriter.write(Integer.toString(warnings.size()));
      mWriter.write("</td>");
      
      mWriter.write("<td class=\"issueColumn\">");
      
      String imageUrl = isError ? errorUrl : warningUrl;
      if (imageUrl != null)
      {
        mWriter.write("<img border=\"0\" align=\"top\" src=\"");
        mWriter.write(imageUrl);
        mWriter.write("\" alt=\"");
        mWriter.write(isError ? "Error" : "Warning");
        mWriter.write("\" />\n");
      }
      mWriter.write("<a href=\"#");
      mWriter.write(issue.getId());
      mWriter.write("\">");
      mWriter.write(issue.getId());
      mWriter.write(": ");
      mWriter.write(issue.getBriefDescription(Issue.OutputFormat.HTML));
      mWriter.write("</a>\n");
      
      mWriter.write("</td></tr>\n");
    }
    if ((missingCount > 0) && (!mClient.isCheckingSpecificIssues()))
    {
      mWriter.write("<tr><td></td>");
      mWriter.write("<td class=\"categoryColumn\">");
      mWriter.write("<a href=\"#MissingIssues\">");
      mWriter.write(String.format("Disabled Checks (%1$d)", new Object[] { Integer.valueOf(missingCount) }));
      
      mWriter.write("</a>\n");
      mWriter.write("</td></tr>");
    }
    mWriter.write("</table>\n");
    mWriter.write("<br/>");
  }
  
  private String writeLocation(File file, String path, int line)
    throws IOException
  {
    mWriter.write("<span class=\"location\">");
    
    String url = getUrl(file);
    if (url != null)
    {
      mWriter.write("<a href=\"");
      mWriter.write(url);
      mWriter.write("\">");
    }
    String displayPath = stripPath(path);
    if ((url != null) && (url.startsWith("../")) && (new File(displayPath).isAbsolute())) {
      displayPath = url;
    }
    mWriter.write(displayPath);
    if (url != null) {
      mWriter.write("</a>");
    }
    if (line >= 0)
    {
      mWriter.write(58);
      mWriter.write(Integer.toString(line + 1));
    }
    mWriter.write("</span>");
    return url;
  }
  
  private boolean addImage(String url, Location location)
    throws IOException
  {
    if ((url != null) && (LintUtils.endsWith(url, ".png")))
    {
      if (location.getSecondary() != null)
      {
        List<String> urls = new ArrayList();
        while ((location != null) && (location.getFile() != null))
        {
          String imageUrl = getUrl(location.getFile());
          if ((imageUrl != null) && (LintUtils.endsWith(imageUrl, ".png"))) {
            urls.add(imageUrl);
          }
          location = location.getSecondary();
        }
        if (!urls.isEmpty())
        {
          Collections.sort(urls, new Comparator()
          {
            public int compare(String s1, String s2)
            {
              return HtmlReporter.getDpiRank(s1) - HtmlReporter.getDpiRank(s2);
            }
          });
          mWriter.write("<table>");
          mWriter.write("<tr>");
          for (String linkedUrl : urls)
          {
            mWriter.write("<td>");
            mWriter.write("<a href=\"");
            mWriter.write(linkedUrl);
            mWriter.write("\">");
            mWriter.write("<img border=\"0\" align=\"top\" src=\"");
            mWriter.write(linkedUrl);
            mWriter.write("\" /></a>\n");
            mWriter.write("</td>");
          }
          mWriter.write("</tr>");
          
          mWriter.write("<tr>");
          for (String linkedUrl : urls)
          {
            mWriter.write("<th>");
            int index = linkedUrl.lastIndexOf("drawable-");
            if (index != -1)
            {
              index += "drawable-".length();
              int end = linkedUrl.indexOf('/', index);
              if (end != -1) {
                mWriter.write(linkedUrl.substring(index, end));
              }
            }
            mWriter.write("</th>");
          }
          mWriter.write("</tr>\n");
          
          mWriter.write("</table>\n");
        }
      }
      else
      {
        mWriter.write("<img class=\"embedimage\" align=\"right\" src=\"");
        mWriter.write(url);
        mWriter.write("\" />");
      }
      return true;
    }
    return false;
  }
  
  private static int getDpiRank(String url)
  {
    if (url.contains("-xhdpi")) {
      return 0;
    }
    if (url.contains("-hdpi")) {
      return 1;
    }
    if (url.contains("-mdpi")) {
      return 2;
    }
    if (url.contains("-ldpi")) {
      return 3;
    }
    return 4;
  }
  
  private void appendCodeBlock(String contents, int lineno, int offset)
    throws IOException
  {
    int max = lineno + 3;
    int min = lineno - 3;
    for (int l = min; l < max; l++) {
      if (l >= 0)
      {
        int lineOffset = LintCliClient.getLineOffset(contents, l);
        if (lineOffset == -1) {
          break;
        }
        mWriter.write(String.format("<span class=\"lineno\">%1$4d</span> ", new Object[] { Integer.valueOf(l + 1) }));
        
        String line = LintCliClient.getLineOfOffset(contents, lineOffset);
        if ((offset != -1) && (lineOffset <= offset) && (lineOffset + line.length() >= offset))
        {
          int delta = offset - lineOffset;
          appendEscapedText(line.substring(0, delta));
          mWriter.write("<span class=\"errorspan\">");
          appendEscapedText(line.substring(delta));
          mWriter.write("</span>");
        }
        else if ((offset == -1) && (l == lineno))
        {
          mWriter.write("<span class=\"errorline\">");
          appendEscapedText(line);
          mWriter.write("</span>");
        }
        else
        {
          appendEscapedText(line);
        }
        if (l < max - 1) {
          mWriter.write("\n");
        }
      }
    }
  }
  
  protected void appendEscapedText(String textValue)
    throws IOException
  {
    int i = 0;
    for (int n = textValue.length(); i < n; i++)
    {
      char c = textValue.charAt(i);
      if (c == '<')
      {
        mWriter.write("&lt;");
      }
      else if (c == '&')
      {
        mWriter.write("&amp;");
      }
      else if (c == '\n')
      {
        mWriter.write("<br/>\n");
      }
      else if (c > '�')
      {
        mWriter.write("&#");
        mWriter.write(Integer.toString(c));
        mWriter.write(59);
      }
      else
      {
        mWriter.write(c);
      }
    }
  }
  
  private String stripPath(String path)
  {
    if ((mStripPrefix != null) && (path.startsWith(mStripPrefix)) && (path.length() > mStripPrefix.length()))
    {
      int index = mStripPrefix.length();
      if (path.charAt(index) == File.separatorChar) {
        index++;
      }
      return path.substring(index);
    }
    return path;
  }
  
  void setStripPrefix(String prefix)
  {
    mStripPrefix = prefix;
  }
  
  static URL getWarningIconUrl()
  {
    return HtmlReporter.class.getResource("lint-warning.png");
  }
  
  static URL getErrorIconUrl()
  {
    return HtmlReporter.class.getResource("lint-error.png");
  }
}

/* Location:
 * Qualified Name:     com.android.tools.lint.HtmlReporter
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.tools.lint;

class LintCliClient$1 {}

/* Location:
 * Qualified Name:     com.android.tools.lint.LintCliClient.1
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
null
package com.android.tools.lint;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.lint.client.api.LintDriver;
import com.android.tools.lint.client.api.LintListener;
import com.android.tools.lint.client.api.LintListener.EventType;
import com.android.tools.lint.detector.api.Context;
import com.android.tools.lint.detector.api.Project;
import java.io.PrintStream;

class LintCliClient$ProgressPrinter
  implements LintListener
{
  public void update(@NonNull LintDriver lint, @NonNull LintListener.EventType type, @Nullable Context context)
  {
    switch (LintCliClient.1.$SwitchMap$com$android$tools$lint$client$api$LintListener$EventType[type.ordinal()])
    {
    case 1: 
      String name = context != null ? context.getProject().getName() : "?";
      if (lint.getPhase() > 1) {
        System.out.print(String.format("\nScanning %1$s (Phase %2$d): ", new Object[] { name, Integer.valueOf(lint.getPhase()) }));
      } else {
        System.out.print(String.format("\nScanning %1$s: ", new Object[] { name }));
      }
      break;
    case 2: 
      String name = context != null ? context.getProject().getName() : "?";
      System.out.print(String.format("\n         - %1$s: ", new Object[] { name }));
      
      break;
    case 3: 
      System.out.print('.');
      break;
    case 4: 
      break;
    case 5: 
    case 6: 
      System.out.println();
      break;
    }
  }
}

/* Location:
 * Qualified Name:     com.android.tools.lint.LintCliClient.ProgressPrinter
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
null
package com.android.tools.lint;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.google.common.annotations.Beta;
import com.google.common.collect.Lists;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Beta
public class LintCliFlags
{
  private final Set<String> mSuppress = new HashSet();
  private final Set<String> mEnabled = new HashSet();
  private Set<String> mCheck = null;
  private boolean mSetExitCode;
  private boolean mFullPath;
  private boolean mShowLines = true;
  private final List<Reporter> mReporters = Lists.newArrayList();
  private boolean mQuiet;
  private boolean mWarnAll;
  private boolean mNoWarnings;
  private boolean mAllErrors;
  private boolean mFatalOnly;
  private List<File> mSources;
  private List<File> mClasses;
  private List<File> mLibraries;
  private List<File> mResources;
  private File mDefaultConfiguration;
  private boolean mShowAll;
  public static final int ERRNO_SUCCESS = 0;
  public static final int ERRNO_ERRORS = 1;
  public static final int ERRNO_USAGE = 2;
  public static final int ERRNO_EXISTS = 3;
  public static final int ERRNO_HELP = 4;
  public static final int ERRNO_INVALID_ARGS = 5;
  
  @NonNull
  public Set<String> getSuppressedIds()
  {
    return mSuppress;
  }
  
  @NonNull
  public Set<String> getEnabledIds()
  {
    return mEnabled;
  }
  
  @Nullable
  public Set<String> getExactCheckedIds()
  {
    return mCheck;
  }
  
  public void setExactCheckedIds(@Nullable Set<String> check)
  {
    mCheck = check;
  }
  
  public boolean isSetExitCode()
  {
    return mSetExitCode;
  }
  
  public void setSetExitCode(boolean setExitCode)
  {
    mSetExitCode = setExitCode;
  }
  
  public boolean isFullPath()
  {
    return mFullPath;
  }
  
  public void setFullPath(boolean fullPath)
  {
    mFullPath = fullPath;
  }
  
  public boolean isShowSourceLines()
  {
    return mShowLines;
  }
  
  public void setShowSourceLines(boolean showLines)
  {
    mShowLines = showLines;
  }
  
  @NonNull
  public List<Reporter> getReporters()
  {
    return mReporters;
  }
  
  public boolean isQuiet()
  {
    return mQuiet;
  }
  
  public void setQuiet(boolean quiet)
  {
    mQuiet = quiet;
  }
  
  public boolean isCheckAllWarnings()
  {
    return mWarnAll;
  }
  
  public void setCheckAllWarnings(boolean warnAll)
  {
    mWarnAll = warnAll;
  }
  
  public boolean isIgnoreWarnings()
  {
    return mNoWarnings;
  }
  
  public void setIgnoreWarnings(boolean noWarnings)
  {
    mNoWarnings = noWarnings;
  }
  
  public boolean isWarningsAsErrors()
  {
    return mAllErrors;
  }
  
  public void setWarningsAsErrors(boolean allErrors)
  {
    mAllErrors = allErrors;
  }
  
  public boolean isShowEverything()
  {
    return mShowAll;
  }
  
  public void setShowEverything(boolean showAll)
  {
    mShowAll = showAll;
  }
  
  @Nullable
  public File getDefaultConfiguration()
  {
    return mDefaultConfiguration;
  }
  
  public void setDefaultConfiguration(@Nullable File defaultConfiguration)
  {
    mDefaultConfiguration = defaultConfiguration;
  }
  
  @Nullable
  public List<File> getSourcesOverride()
  {
    return mSources;
  }
  
  public void setSourcesOverride(@Nullable List<File> sources)
  {
    mSources = sources;
  }
  
  @Nullable
  public List<File> getClassesOverride()
  {
    return mClasses;
  }
  
  public void setClassesOverride(@Nullable List<File> classes)
  {
    mClasses = classes;
  }
  
  @Nullable
  public List<File> getLibrariesOverride()
  {
    return mLibraries;
  }
  
  public void setLibrariesOverride(@Nullable List<File> libraries)
  {
    mLibraries = libraries;
  }
  
  @Nullable
  public List<File> getResourcesOverride()
  {
    return mResources;
  }
  
  public void setResourcesOverride(@Nullable List<File> resources)
  {
    mResources = resources;
  }
  
  public boolean isFatalOnly()
  {
    return mFatalOnly;
  }
  
  public void setFatalOnly(boolean fatalOnly)
  {
    mFatalOnly = fatalOnly;
  }
}

/* Location:
 * Qualified Name:     com.android.tools.lint.LintCliFlags
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.tools.lint;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.Location.Handle;
import java.io.File;
import org.w3c.dom.Node;

class LintCliXmlParser$LocationHandle
  implements Location.Handle
{
  private final File mFile;
  private final Node mNode;
  private Object mClientData;
  
  public LintCliXmlParser$LocationHandle(LintCliXmlParser paramLintCliXmlParser, File file, Node node)
  {
    mFile = file;
    mNode = node;
  }
  
  @NonNull
  public Location resolve()
  {
    LintCliXmlParser.OffsetPosition pos = (LintCliXmlParser.OffsetPosition)this$0.getPosition(mNode);
    if (pos != null) {
      return Location.create(mFile, pos, (LintCliXmlParser.OffsetPosition)pos.getEnd());
    }
    return Location.create(mFile);
  }
  
  public void setClientData(@Nullable Object clientData)
  {
    mClientData = clientData;
  }
  
  @Nullable
  public Object getClientData()
  {
    return mClientData;
  }
}

/* Location:
 * Qualified Name:     com.android.tools.lint.LintCliXmlParser.LocationHandle
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.tools.lint;

import com.android.annotations.NonNull;
import com.android.tools.lint.detector.api.Position;
import com.android.utils.PositionXmlParser.Position;

class LintCliXmlParser$OffsetPosition
  extends Position
  implements PositionXmlParser.Position
{
  private final int mLine;
  private final int mColumn;
  private final int mOffset;
  private PositionXmlParser.Position mEnd;
  
  public LintCliXmlParser$OffsetPosition(int line, int column, int offset)
  {
    mLine = line;
    mColumn = column;
    mOffset = offset;
  }
  
  public int getLine()
  {
    return mLine;
  }
  
  public int getOffset()
  {
    return mOffset;
  }
  
  public int getColumn()
  {
    return mColumn;
  }
  
  public PositionXmlParser.Position getEnd()
  {
    return mEnd;
  }
  
  public void setEnd(@NonNull PositionXmlParser.Position end)
  {
    mEnd = end;
  }
  
  public String toString()
  {
    return "OffsetPosition [line=" + mLine + ", column=" + mColumn + ", offset=" + mOffset + ", end=" + mEnd + ']';
  }
}

/* Location:
 * Qualified Name:     com.android.tools.lint.LintCliXmlParser.OffsetPosition
 * Java Class Version: 6 (50.0)
 * JD-Co
1 2 3

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2017. Infinite Loop Ltd