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

com.google.auto.value.processor.JavaScanner Maven / Gradle / Ivy

There is a newer version: 1.11.0
Show newest version
/*
 * Copyright (C) 2015 Google, Inc.
 *
 * 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.google.auto.value.processor;

/**
 * A simplistic Java scanner. This scanner returns a sequence of tokens that can be used to
 * reconstruct the source code. Since the source code is coming from a string, the scanner in fact
 * just returns token boundaries rather than the tokens themselves.
 *
 * 

We are not dealing with arbitrary user code so we can assume there are no exotic things like * tabs or Unicode escapes that resolve into quotes. The purpose of the scanner here is to return a * sequence of offsets that split the string up in a way that allows us to work with spaces without * having to worry whether they are inside strings or comments. The particular properties we use are * that every string and character literal and every comment is a single token; every newline plus * all following indentation is a single token; and every other string of consecutive spaces outside * a comment or literal is a single token. That means that we can safely compress a token that * starts with a space into a single space, without falsely removing indentation or changing the * contents of strings. * *

In addition to real Java syntax, this scanner recognizes tokens of the form {@code `text`}, * which are used in the templates to wrap fully-qualified type names, so that they can be extracted * and replaced by imported names if possible. * * @author Éamonn McManus */ class JavaScanner { private final String s; JavaScanner(String s) { if (!s.endsWith("\n")) { s += "\n"; // This allows us to avoid checking for the end of the string in most cases. } this.s = s; } int tokenEnd(int start) { if (start >= s.length()) { return s.length(); } switch (s.charAt(start)) { case ' ': case '\n': return spaceEnd(start); case '/': if (s.charAt(start + 1) == '*') { return blockCommentEnd(start); } else if (s.charAt(start + 1) == '/') { return lineCommentEnd(start); } else { return start + 1; } case '\'': case '"': case '`': return quoteEnd(start); default: // Every other character is considered to be its own token. return start + 1; } } private int spaceEnd(int start) { assert s.charAt(start) == ' ' || s.charAt(start) == '\n'; int i; for (i = start + 1; i < s.length() && s.charAt(i) == ' '; i++) {} return i; } private int blockCommentEnd(int start) { assert s.charAt(start) == '/' && s.charAt(start + 1) == '*'; int i; for (i = start + 2; s.charAt(i) != '*' || s.charAt(i + 1) != '/'; i++) {} return i + 2; } private int lineCommentEnd(int start) { assert s.charAt(start) == '/' && s.charAt(start + 1) == '/'; int end = s.indexOf('\n', start + 2); assert end > 0; return end; } private int quoteEnd(int start) { char quote = s.charAt(start); assert quote == '\'' || quote == '"' || quote == '`'; int i; for (i = start + 1; s.charAt(i) != quote; i++) { if (s.charAt(i) == '\\') { i++; } } return i + 1; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy