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

nl.topicus.jdbc.shaded.com.google.auto.value.processor.JavaScanner Maven / Gradle / Ivy

/*
 * 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 nl.topicus.jdbc.shaded.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 */ // This scanner is different from the one in EclipseHackTokenizer (which is only needed for // EclipseHack). The needs of the two scanner are very different: EclipseHackTokenizer is only // needed to scan through an existing source file to find abstract method declarations, so it // can discard everything that isn't needed for that, including comments and string literals for // example. Meanwhile, this scanner needs to return a sequence of tokens that can be used to // reconstruct the source code. EclipseHackTokenizer also operates on a Reader (which in practice is // coming from a file), while here we already have the source code in a String, which means that we // can just return token boundaries rather than the tokens themselves. 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