/*******************************************************************************
* Copyright (c) 2016 Bruno Medeiros and other Contributors.
* 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:
* Bruno Medeiros - initial API and implementation
*******************************************************************************/
package com.googlecode.goclipse.tooling.oracle;
import melnorme.lang.utils.parse.LexingUtils;
import melnorme.lang.utils.parse.StringCharSource;
public class GoDocParser {
public String parseDocForDefinitionAt(String text, int offset) {
StringBuilder docSB = null;
String commentPrefix = null;
while(true) {
int lineStart = findStartPosOfPreviousLine(text, offset);
if(lineStart == -1) {
break;
}
if(commentPrefix == null) {
// Determine comment prefix (some optional whitespace followed by "//"
commentPrefix = getCommentPrefix(text, lineStart);
if(commentPrefix == null) {
// No valid comment found, no doc available
return null;
}
} else {
// For next line above to be added, it must have the same comment prefix
// (same amount of whitespace and "//")
if(!text.regionMatches(lineStart, commentPrefix, 0, commentPrefix.length())) {
break;
}
}
if(docSB == null) {
docSB = new StringBuilder();
}
docSB.insert(0, getLineTextAt(text, lineStart+commentPrefix.length()));
offset = lineStart;
}
if(docSB == null) {
return null;
}
return docSB.toString().trim();
}
public int findStartPosOfPreviousLine(String source, int offset) {
int index = source.lastIndexOf('\n', offset-1); // note, -1 is a valid argument
if(index == -1) {
return -1; // There is no previous line
}
// Index now at end of previous line, find the start
index = source.lastIndexOf('\n', index-1); // note, -1 is a valid argument
if(index == -1) {
return 0; // It's the first line, which starts at 0
}
return index + 1;
}
public String getCommentPrefix(String text, int lineStart) {
for(int ix = lineStart; ix+1 < text.length(); ix++) {
char ch = text.charAt(ix);
if(Character.isSpaceChar(ch) || ch == '\t') {
continue;
}
if(ch == '/' && text.charAt(ix+1) == '/' ) {
return text.substring(lineStart, ix+2);
} else {
break;
}
}
return null; // Not found
}
public String getLineTextAt(String text, int offset) {
StringCharSource charSource = new StringCharSource(text);
charSource.consumeAmount(offset);
return LexingUtils.stringUntilNewline(charSource);
}
}