blob: 6b232c56a7cfc846a3670db7f498ae40d4f1ada8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 BEA Systems, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* jgarms@bea.com - initial API and implementation
*
*******************************************************************************/
package org.eclipse.jdt.apt.core.internal.util;
import java.io.IOException;
import static org.eclipse.jdt.apt.core.internal.util.AnnotationScanner.State.*;
/**
* Utility scanner for quickly determining if a file contains annotations
*/
public abstract class AnnotationScanner {
enum State {
NORMAL,
SEEN_SLASH,
IN_COMMENT,
IN_COMMENT_SEEN_STAR,
IN_SINGLE_LINE_COMMENT,
IN_SINGLE_QUOTE,
IN_DOUBLE_QUOTE
}
public AnnotationScanner() {}
public boolean containsAnnotations() throws IOException {
State state = NORMAL;
// for escaping quotes -- need to ignore the next single character
// Since this applies to all states it's handled separately
boolean seenBackslash = false;
int c = getNext();
while (c != -1) {
if (seenBackslash) {
// Skip one character
seenBackslash = false;
}
else if (c == '\\') {
// Skip the next character
seenBackslash = true;
}
else {
// Handle the character based on state
switch (state) {
case NORMAL :
if (c == '@')
return true;
if (c == '/') {
state = SEEN_SLASH;
}
else if (c == '\'') {
state = IN_SINGLE_QUOTE;
}
else if (c == '\"') {
state = IN_DOUBLE_QUOTE;
}
break;
case SEEN_SLASH :
if (c == '*') {
state = IN_COMMENT;
}
else if (c == '/') {
state = IN_SINGLE_LINE_COMMENT;
}
else {
state = NORMAL;
}
break;
case IN_COMMENT :
if (c == '*') {
state = IN_COMMENT_SEEN_STAR;
}
break;
case IN_COMMENT_SEEN_STAR :
if (c == '/') {
state = NORMAL;
}
else {
state = IN_COMMENT;
}
break;
case IN_SINGLE_LINE_COMMENT :
if (c == '\n' || c == '\r') {
state = NORMAL;
}
break;
case IN_SINGLE_QUOTE :
if (c == '\'') {
state = NORMAL;
}
break;
case IN_DOUBLE_QUOTE :
if (c == '\"') {
state = NORMAL;
}
break;
default :
throw new IllegalStateException("Unhandled state: " + state); //$NON-NLS-1$
}
}
c = getNext();
}
return false;
}
/**
* Returns -1 at the end of the input
*/
protected abstract int getNext() throws IOException;
}