All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.android.tools.idea.gradle.output.parser.javac.JavacOutputParser Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition android-common library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.tools.idea.gradle.output.parser.javac;

import com.android.SdkConstants;
import com.android.ide.common.blame.output.GradleMessage;
import com.android.ide.common.blame.parser.ParsingFailedException;
import com.android.ide.common.blame.parser.PatternAwareOutputParser;
import com.android.ide.common.blame.parser.util.OutputLineReader;
import com.android.utils.ILogger;
import com.google.common.collect.Lists;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.util.List;

/**
 * Parses javac's output.
 */
public class JavacOutputParser implements PatternAwareOutputParser {
  private static final char COLON = ':';

  private static final String WARNING_PREFIX = "warning:"; // default value

  @Override
  public boolean parse(@NotNull String line, @NotNull OutputLineReader reader, @NotNull List messages, @NotNull ILogger logger)
    throws ParsingFailedException {
    int colonIndex1 = line.indexOf(COLON);
    if (colonIndex1 == 1) { // drive letter (Windows)
      colonIndex1 = line.indexOf(COLON, colonIndex1 + 1);
    }

    if (colonIndex1 >= 0) { // looks like found something like a file path.
      String part1 = line.substring(0, colonIndex1).trim();
      if (part1.equalsIgnoreCase("error") /* jikes */ || part1.equalsIgnoreCase("Caused by")) {
        // +1 so we don't include the colon
        String text = line.substring(colonIndex1 + 1).trim();
        addMessage(new GradleMessage(GradleMessage.Kind.ERROR, text), messages);
        return true;
      }
      if (part1.equalsIgnoreCase("warning")) {
        // +1 so we don't include the colon
        String text = line.substring(colonIndex1 + 1).trim();
        addMessage(new GradleMessage(GradleMessage.Kind.WARNING, text), messages);
        return true;
      }
      if (part1.equalsIgnoreCase("javac")) {
        addMessage(new GradleMessage(GradleMessage.Kind.ERROR, line), messages);
        return true;
      }

      int colonIndex2 = line.indexOf(COLON, colonIndex1 + 1);
      if (colonIndex2 >= 0) {
        File file = new File(part1);
        if (!file.isFile()) {
          // the part one is not a file path.
          return false;
        }
        try {
          int lineNumber = Integer.parseInt(line.substring(colonIndex1 + 1, colonIndex2).trim());
          String text = line.substring(colonIndex2 + 1).trim();
          GradleMessage.Kind kind = GradleMessage.Kind.ERROR;

          if (text.startsWith(WARNING_PREFIX)) {
            text = text.substring(WARNING_PREFIX.length()).trim();
            kind = GradleMessage.Kind.WARNING;
          }

          // Only slurp up line pointer (^) information if this is really javac
          if (!file.getPath().endsWith(SdkConstants.DOT_JAVA)) {
            // Fall back to the MergingExceptionParser (which handles similar messages in a more general way)
            return false;
          }

          List messageList = Lists.newArrayList();
          messageList.add(text);
          int column;
          String prevLine = null;
          do {
            String nextLine = reader.readLine();
            if (nextLine == null) {
              return false;
            }
            if (nextLine.trim().equals("^")) {
              column = nextLine.indexOf('^');
              String messageEnd = reader.readLine();

              while (isMessageEnd(messageEnd)) {
                messageList.add(messageEnd.trim());
                messageEnd = reader.readLine();
              }

              if (messageEnd != null) {
                reader.pushBack(messageEnd);
              }
              break;
            }
            if (prevLine != null) {
              messageList.add(prevLine);
            }
            prevLine = nextLine;
          } while (true);

          if (column >= 0) {
            messageList = convertMessages(messageList);
            StringBuilder buf = StringBuilderSpinAllocator.alloc();
            try {
              for (String m : messageList) {
                if (buf.length() > 0) {
                  buf.append(SystemProperties.getLineSeparator()) ;
                }
                buf.append(m);
              }
              GradleMessage msg = new GradleMessage(kind, buf.toString(), file.getAbsolutePath(), lineNumber, column + 1);
              addMessage(msg, messages);
            } finally {
              StringBuilderSpinAllocator.dispose(buf);
            }
            return true;
          }

        } catch (NumberFormatException ignored) {
        }
      }
    }

    if (line.endsWith("java.lang.OutOfMemoryError")) {
      addMessage(new GradleMessage(GradleMessage.Kind.ERROR, "Out of memory."), messages);
      return true;
    }

    return false;
  }

  private static void addMessage(@NotNull GradleMessage message, @NotNull List messages) {
    boolean duplicatesPrevious = false;
    int messageCount = messages.size();
    if (messageCount > 0) {
      GradleMessage lastMessage = messages.get(messageCount - 1);
      duplicatesPrevious = lastMessage.equals(message);
    }
    if (!duplicatesPrevious) {
      messages.add(message);
    }
  }

  @Contract("null -> false")
  private static boolean isMessageEnd(@Nullable String line) {
    return line != null && line.length() > 0 && Character.isWhitespace(line.charAt(0));
  }

  @NotNull
  private static List convertMessages(@NotNull List messages) {
    if(messages.size() <= 1) {
      return messages;
    }
    final String line0 = messages.get(0);
    final String line1 = messages.get(1);
    final int colonIndex = line1.indexOf(':');
    if (colonIndex > 0){
      @NonNls String part1 = line1.substring(0, colonIndex).trim();
      // jikes
      if ("symbol".equals(part1)){
        String symbol = line1.substring(colonIndex + 1).trim();
        messages.remove(1);
        if(messages.size() >= 2) {
          messages.remove(1);
        }
        messages.set(0, line0 + " " + symbol);
      }
    }
    return messages;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy