1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Migrate AsmModelBuilder to new Lexer

This commit is contained in:
Anton Leherbauer 2007-11-06 15:01:22 +00:00
parent 1be0d21863
commit 5ec0f9d046
3 changed files with 192 additions and 166 deletions

View file

@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.IAsmLabel; import org.eclipse.cdt.core.model.IAsmLabel;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IInclude;
import org.eclipse.cdt.core.model.IParent; import org.eclipse.cdt.core.model.IParent;
import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ISourceReference;
@ -58,38 +59,44 @@ public class AsmModelBuilderTest extends BaseTestCase {
public void testAsmModelElements() throws Exception { public void testAsmModelElements() throws Exception {
ICElement[] children= fTU.getChildren(); ICElement[] children= fTU.getChildren();
assertEquals(7, children.length); assertEquals(8, children.length);
assertEquals(ICElement.C_INCLUDE, children[0].getElementType()); int idx= 0;
assertEquals("include.h", children[0].getElementName()); assertEquals(ICElement.C_INCLUDE, children[idx].getElementType());
assertTrue(((IInclude)children[idx]).isStandard());
assertEquals("include1.h", children[idx++].getElementName());
assertEquals(ICElement.C_INCLUDE, children[idx].getElementType());
assertFalse(((IInclude)children[idx]).isStandard());
assertEquals("include2.h", children[idx++].getElementName());
assertEquals(ICElement.ASM_LABEL, children[1].getElementType());
assertEquals("nonGlobalLabel", children[1].getElementName());
assertFalse(((IAsmLabel)children[1]).isGlobal());
assertEquals(0, ((IParent)children[1]).getChildren().length);
assertEquals(ICElement.ASM_LABEL, children[2].getElementType()); assertEquals(ICElement.ASM_LABEL, children[idx].getElementType());
assertEquals("globalLabel1", children[2].getElementName()); assertEquals("nonGlobalLabel", children[idx].getElementName());
assertTrue(((IAsmLabel)children[2]).isGlobal()); assertFalse(((IAsmLabel)children[idx]).isGlobal());
assertEquals(2, ((IParent)children[2]).getChildren().length); assertEquals(0, ((IParent)children[idx++]).getChildren().length);
assertEquals(ICElement.C_MACRO, children[3].getElementType()); assertEquals(ICElement.ASM_LABEL, children[idx].getElementType());
assertEquals("MACRO", children[3].getElementName()); assertEquals("globalLabel1", children[idx].getElementName());
assertTrue(((IAsmLabel)children[idx]).isGlobal());
assertEquals(2, ((IParent)children[idx++]).getChildren().length);
assertEquals(ICElement.ASM_LABEL, children[4].getElementType()); assertEquals(ICElement.C_MACRO, children[idx].getElementType());
assertEquals("globalLabel2", children[4].getElementName()); assertEquals("MACRO", children[idx++].getElementName());
assertTrue(((IAsmLabel)children[4]).isGlobal());
assertEquals(1, ((IParent)children[4]).getChildren().length);
assertEquals(ICElement.ASM_LABEL, children[5].getElementType()); assertEquals(ICElement.ASM_LABEL, children[idx].getElementType());
assertEquals("globalLabel3", children[5].getElementName()); assertEquals("globalLabel2", children[idx].getElementName());
assertTrue(((IAsmLabel)children[5]).isGlobal()); assertTrue(((IAsmLabel)children[idx]).isGlobal());
assertEquals(1, ((IParent)children[5]).getChildren().length); assertEquals(1, ((IParent)children[idx++]).getChildren().length);
assertEquals(ICElement.ASM_LABEL, children[6].getElementType()); assertEquals(ICElement.ASM_LABEL, children[idx].getElementType());
assertEquals("alloca", children[6].getElementName()); assertEquals("globalLabel3", children[idx].getElementName());
assertTrue(((IAsmLabel)children[6]).isGlobal()); assertTrue(((IAsmLabel)children[idx]).isGlobal());
assertEquals(0, ((IParent)children[6]).getChildren().length); assertEquals(1, ((IParent)children[idx++]).getChildren().length);
assertEquals(ICElement.ASM_LABEL, children[idx].getElementType());
assertEquals("alloca", children[idx].getElementName());
assertTrue(((IAsmLabel)children[idx]).isGlobal());
assertEquals(0, ((IParent)children[idx++]).getChildren().length);
} }
public void testAsmLabelRanges() throws Exception { public void testAsmLabelRanges() throws Exception {

View file

@ -2,7 +2,8 @@
* AsmTest.S * AsmTest.S
*/ */
#include <include.h> #include <include1.h>
#include "include2.h"
.globl globalLabel1 .globl globalLabel1
.global globalLabel2, globalLabel3 .global globalLabel2, globalLabel3
@ -39,7 +40,7 @@ otherLabel2:
movb $0x81, %ah ; end-of-line comment movb $0x81, %ah ; end-of-line comment
jmp globalLabel3 # comment jmp globalLabel3 # comment
/* end */ /* end */
globalLabel3: globalLabel3:
movl %esp, %eax movl %esp, %eax
movl %eax, storage movl %eax, storage
@ -47,6 +48,7 @@ globalLabel3:
otherLabel3: otherLabel3:
movb $0x81, %ah movb $0x81, %ah
jmp globalLabel3 jmp globalLabel3
nop
/* end */ /* end */
.global alloca .global alloca

View file

@ -12,14 +12,19 @@
package org.eclipse.cdt.internal.core.model; package org.eclipse.cdt.internal.core.model;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.model.AssemblyLanguage; import org.eclipse.cdt.core.model.AssemblyLanguage;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.IContributedModelBuilder; import org.eclipse.cdt.core.model.IContributedModelBuilder;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.internal.formatter.scanner.Scanner; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.formatter.scanner.Token; import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
import org.eclipse.cdt.internal.core.parser.scanner.ILexerLog;
import org.eclipse.cdt.internal.core.parser.scanner.Lexer;
import org.eclipse.cdt.internal.core.parser.scanner.Token;
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
/** /**
* A simple model builder for assembly translation units. * A simple model builder for assembly translation units.
@ -31,31 +36,44 @@ import org.eclipse.cdt.internal.formatter.scanner.Token;
*/ */
public class AsmModelBuilder implements IContributedModelBuilder { public class AsmModelBuilder implements IContributedModelBuilder {
private static final class AsmDirective {
private static final AsmDirective GLOBAL= new AsmDirective();
private static final AsmDirective DATA= new AsmDirective();
}
private static final class LexerLog implements ILexerLog {
public void handleComment(boolean isBlockComment, int offset, int endOffset) {
}
public void handleProblem(int problemID, char[] info, int offset, int endOffset) {
}
}
private static final class Counter { private static final class Counter {
int fCount; int fCount;
} }
private final static class Tokenizer extends Scanner { private static final Map fgDirectives;
public Tokenizer(char[] source) {
setSource(source); static {
} fgDirectives= new HashMap();
fgDirectives.put("globl", AsmDirective.GLOBAL); //$NON-NLS-1$
public Token nextToken() { fgDirectives.put("global", AsmDirective.GLOBAL); //$NON-NLS-1$
Token t= super.nextToken(); fgDirectives.put("ascii", AsmDirective.DATA); //$NON-NLS-1$
while (t != null && (t.isWhiteSpace())) { fgDirectives.put("asciz", AsmDirective.DATA); //$NON-NLS-1$
t= super.nextToken(); fgDirectives.put("byte", AsmDirective.DATA); //$NON-NLS-1$
} fgDirectives.put("long", AsmDirective.DATA); //$NON-NLS-1$
return t; fgDirectives.put("word", AsmDirective.DATA); //$NON-NLS-1$
}
} }
private TranslationUnit fTranslationUnit; private TranslationUnit fTranslationUnit;
private char fLineSeparatorChar; private char fLineSeparatorChar;
private HashMap fGlobals; private Map fGlobals;
private HashMap fLabels; private Map fLabels;
private int fLastLabelEndOffset; private int fLastLabelEndOffset;
private AsmLabel fLastGlobalLabel; private AsmLabel fLastGlobalLabel;
private SourceManipulation fLastLabel; private SourceManipulation fLastLabel;
private Lexer fLexer;
/** /**
* Creates a model builder for the given assembly translation unit. * Creates a model builder for the given assembly translation unit.
@ -87,8 +105,10 @@ public class AsmModelBuilder implements IContributedModelBuilder {
buildModel(reader.buffer); buildModel(reader.buffer);
// not sure whether this is necessary or not // not sure whether this is necessary or not
fTranslationUnit.setIsStructureKnown(true); fTranslationUnit.setIsStructureKnown(true);
// cleanup
fGlobals= null; fGlobals= null;
fLabels= null; fLabels= null;
fLexer= null;
} }
/** /**
@ -96,6 +116,7 @@ public class AsmModelBuilder implements IContributedModelBuilder {
* *
* @param source * @param source
* @throws CModelException * @throws CModelException
* @throws OffsetLimitReachedException
*/ */
private void buildModel(final char[] source) throws CModelException { private void buildModel(final char[] source) throws CModelException {
fGlobals= new HashMap(); fGlobals= new HashMap();
@ -104,10 +125,8 @@ public class AsmModelBuilder implements IContributedModelBuilder {
fLastGlobalLabel= null; fLastGlobalLabel= null;
fLastLabelEndOffset= 0; fLastLabelEndOffset= 0;
// TLETODO use new Lexer? final LexerOptions lexerOptions= new LexerOptions();
Scanner scanner= new Scanner(); fLexer= new Lexer(source, lexerOptions, new LexerLog(), null);
scanner.setSplitPreprocessor(true);
scanner.setSource(source);
// if true the next token is the first on a (logical) line // if true the next token is the first on a (logical) line
boolean firstTokenOnLine= true; boolean firstTokenOnLine= true;
@ -116,56 +135,39 @@ public class AsmModelBuilder implements IContributedModelBuilder {
// inside instruction // inside instruction
boolean inInstruction= false; boolean inInstruction= false;
Token token= scanner.nextToken(); IToken token= nextToken();
while (token != null) { while (token != null) {
int type= adaptTokenType(token); switch (token.getType()) {
switch (type) { case IToken.tPOUND:
case Token.tPREPROCESSOR_INCLUDE: if (fLexer.currentTokenIsFirstOnLine()) {
parseInclude(fTranslationUnit, token); parsePPDirective(fTranslationUnit);
break;
case Token.tPREPROCESSOR_DEFINE:
parseDefine(fTranslationUnit, token);
break;
case Token.tFLOATINGPT:
if (token.getText().startsWith(".")) { //$NON-NLS-1$
// move scanner behind '.'
scanner.setCurrentPosition(scanner.getCurrentTokenStartPosition() + 1);
// fallthrough
} else {
break;
} }
case Token.tDOT: break;
case IToken.tDOT:
// assembly directive? // assembly directive?
firstTokenOnLine= false; firstTokenOnLine= false;
if (expectInstruction) { if (expectInstruction) {
expectInstruction= false; expectInstruction= false;
int pos= scanner.getCurrentPosition(); token= nextToken();
token= scanner.nextToken(); if (token != null && token.getType() == IToken.tIDENTIFIER) {
if (token != null && adaptTokenType(token) == Token.tIDENTIFIER) { String text= token.getImage();
String text= token.getText();
if (isGlobalDirective(text)) { if (isGlobalDirective(text)) {
firstTokenOnLine= parseGlobalDirective(token, scanner); firstTokenOnLine= parseGlobalDirective(token);
} else if (isDataDirective(text)) { } else if (isDataDirective(text)) {
inInstruction= true; inInstruction= true;
fLastLabelEndOffset= scanner.getCurrentTokenEndPosition();
} }
} else {
scanner.setCurrentPosition(pos);
} }
} }
break; break;
case Token.tIDENTIFIER: case IToken.tIDENTIFIER:
// identifier may be a label or part of an instruction // identifier may be a label or part of an instruction
if (firstTokenOnLine) { if (firstTokenOnLine) {
int pos= scanner.getCurrentPosition(); // peek next char
int ch= scanner.getNextChar(); char nextChar= source[token.getEndOffset()];
if (ch == ':') { if (nextChar == ':') {
parseLabel(fTranslationUnit, token); createLabel(fTranslationUnit, token);
fLastLabelEndOffset= scanner.getCurrentPosition();
expectInstruction= true; expectInstruction= true;
} else { } else {
fLastLabelEndOffset= scanner.getCurrentTokenEndPosition();
scanner.setCurrentPosition(pos);
expectInstruction= false; expectInstruction= false;
inInstruction= true; inInstruction= true;
} }
@ -173,18 +175,13 @@ public class AsmModelBuilder implements IContributedModelBuilder {
} else if (expectInstruction){ } else if (expectInstruction){
expectInstruction= false; expectInstruction= false;
inInstruction= true; inInstruction= true;
fLastLabelEndOffset= scanner.getCurrentTokenEndPosition();
} else if (inInstruction) {
fLastLabelEndOffset= scanner.getCurrentTokenEndPosition();
} }
break; break;
case Token.tPREPROCESSOR: case Lexer.tNEWLINE:
case Token.tWHITESPACE:
if (!firstTokenOnLine) { if (!firstTokenOnLine) {
int nlIndex= token.getText().indexOf('\n'); firstTokenOnLine= true;
firstTokenOnLine= nlIndex >= 0; if (inInstruction) {
if (firstTokenOnLine && inInstruction) { fLastLabelEndOffset= fLexer.currentToken().getEndOffset();
fLastLabelEndOffset= scanner.getCurrentTokenStartPosition() + nlIndex + 1;
} }
} }
break; break;
@ -192,7 +189,7 @@ public class AsmModelBuilder implements IContributedModelBuilder {
expectInstruction= false; expectInstruction= false;
firstTokenOnLine= false; firstTokenOnLine= false;
if (fLineSeparatorChar != 0) { if (fLineSeparatorChar != 0) {
if (token.getLength() == 1 && token.getText().charAt(0) == fLineSeparatorChar) { if (token.getLength() == 1 && token.getCharImage()[0] == fLineSeparatorChar) {
firstTokenOnLine= true; firstTokenOnLine= true;
} }
} }
@ -201,10 +198,10 @@ public class AsmModelBuilder implements IContributedModelBuilder {
expectInstruction= true; expectInstruction= true;
inInstruction= false; inInstruction= false;
} }
token= scanner.nextToken(); token= nextToken();
} }
if (!firstTokenOnLine && inInstruction) { if (!firstTokenOnLine && inInstruction) {
fLastLabelEndOffset= scanner.getCurrentTokenEndPosition(); fLastLabelEndOffset= fLexer.currentToken().getEndOffset();
} }
if (fLastLabel != null) { if (fLastLabel != null) {
fixupLastLabel(); fixupLastLabel();
@ -214,45 +211,36 @@ public class AsmModelBuilder implements IContributedModelBuilder {
} }
} }
/** protected IToken nextToken() {
* Adapt non-identifier tokens to identifier type if they look like valid asm words. Token token;
* try {
* @param token token= fLexer.nextToken();
* @return the adapted token type if (token.getType() == Lexer.tEND_OF_INPUT) {
*/ token = null;
private int adaptTokenType(Token token) {
int type= token.getType();
if (type != Token.tIDENTIFIER) {
if (Character.isUnicodeIdentifierStart(token.getText().charAt(0))) {
type= Token.tIDENTIFIER;
} }
} catch (OffsetLimitReachedException exc) {
token= null;
} }
return type; return token;
} }
private boolean isDataDirective(String directive) { private boolean parseGlobalDirective(IToken token) {
return "byte".equals(directive) || "long".equals(directive) || "word".equals(directive) || "ascii".equals(directive); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
}
private boolean parseGlobalDirective(Token token, Scanner scanner) {
boolean eol= false; boolean eol= false;
do { do {
Token t= scanner.nextToken(); IToken t= nextToken();
if (t == null) { if (t == null) {
break; break;
} }
switch (adaptTokenType(t)) { switch (t.getType()) {
case Token.tIDENTIFIER: case IToken.tIDENTIFIER:
registerGlobalLabel(t.getText()); registerGlobalLabel(t.getImage());
break; break;
case Token.tWHITESPACE: case Lexer.tNEWLINE:
if (token.getText().indexOf('\n') >= 0) { eol= true;
eol= true;
}
break; break;
default: default:
if (fLineSeparatorChar != 0) { if (fLineSeparatorChar != 0) {
if (token.getLength() == 1 && token.getText().charAt(0) == fLineSeparatorChar) { if (token.getLength() == 1 && token.getCharImage()[0] == fLineSeparatorChar) {
eol= true; eol= true;
} }
} }
@ -261,11 +249,15 @@ public class AsmModelBuilder implements IContributedModelBuilder {
return eol; return eol;
} }
private boolean isGlobalDirective(String name) { private static final boolean isDataDirective(String directive) {
return "globl".equals(name) || "global".equals(name); //$NON-NLS-1$ //$NON-NLS-2$ return fgDirectives.get(directive) == AsmDirective.DATA;
} }
private void registerGlobalLabel(String labelName) { private static final boolean isGlobalDirective(String directive) {
return fgDirectives.get(directive) == AsmDirective.GLOBAL;
}
protected void registerGlobalLabel(String labelName) {
Counter counter= (Counter) fGlobals.get(labelName); Counter counter= (Counter) fGlobals.get(labelName);
if (counter == null) { if (counter == null) {
fGlobals.put(labelName, counter= new Counter()); fGlobals.put(labelName, counter= new Counter());
@ -281,7 +273,7 @@ public class AsmModelBuilder implements IContributedModelBuilder {
return counter.fCount; return counter.fCount;
} }
private int registerLabel(String labelName) { protected int registerLabel(String labelName) {
Counter counter= (Counter) fLabels.get(labelName); Counter counter= (Counter) fLabels.get(labelName);
if (counter == null) { if (counter == null) {
fLabels.put(labelName, counter= new Counter()); fLabels.put(labelName, counter= new Counter());
@ -289,8 +281,8 @@ public class AsmModelBuilder implements IContributedModelBuilder {
return counter.fCount++; return counter.fCount++;
} }
private void parseLabel(CElement parent, Token token) throws CModelException { protected void createLabel(CElement parent, IToken token) throws CModelException {
String labelName= token.getText(); String labelName= token.getImage();
int index= getGlobalLabelIndex(labelName); int index= getGlobalLabelIndex(labelName);
boolean global= index > 0; boolean global= index > 0;
if (!global) { if (!global) {
@ -347,68 +339,93 @@ public class AsmModelBuilder implements IContributedModelBuilder {
} }
} }
private void parseDefine(CElement parent, Token token) throws CModelException { private void parsePPDirective(CElement parent) throws CModelException {
final String tokenText= token.getText(); IToken token= nextToken();
Scanner defineScanner= new Tokenizer(tokenText.toCharArray()); if (token != null && token.getType() == IToken.tIDENTIFIER) {
defineScanner.setCurrentPosition(tokenText.indexOf('#') + 1); final String image= token.getImage();
if (image.equals("define")) { //$NON-NLS-1$
try {
parsePPDefine(parent);
} catch (OffsetLimitReachedException exc) {
}
return;
} else if (image.equals("include")) { //$NON-NLS-1$
try {
parsePPInclude(parent);
} catch (OffsetLimitReachedException exc) {
}
return;
}
}
try {
skipToNewLine();
} catch (OffsetLimitReachedException exc) {
}
}
protected int skipToNewLine() throws OffsetLimitReachedException {
return fLexer.consumeLine(fLexer.currentToken().getEndOffset());
}
private void parsePPDefine(CElement parent) throws CModelException, OffsetLimitReachedException {
int startOffset= fLexer.currentToken().getOffset();
int nameStart= 0; int nameStart= 0;
int nameEnd= 0; int nameEnd= 0;
String name= null; String name= null;
Token t= defineScanner.nextToken(); IToken t= nextToken();
if (adaptTokenType(t) == Token.tIDENTIFIER && t.getText().equals("define")) { //$NON-NLS-1$ if (t.getType() == IToken.tIDENTIFIER) {
t= defineScanner.nextToken(); nameStart= fLexer.currentToken().getOffset();
if (adaptTokenType(t) == Token.tIDENTIFIER) { nameEnd= fLexer.currentToken().getEndOffset();
nameStart= defineScanner.getCurrentTokenStartPosition(); name= t.getImage();
nameEnd= defineScanner.getCurrentTokenEndPosition() + 1;
name= t.getText();
}
} }
if (name == null) { if (name == null) {
return; return;
} }
int endOffset= skipToNewLine();
Macro macro= new Macro(parent, name); Macro macro= new Macro(parent, name);
SourceManipulationInfo macroInfo= macro.getSourceManipulationInfo(); SourceManipulationInfo macroInfo= macro.getSourceManipulationInfo();
macroInfo.setIdPos(token.getOffset() + nameStart, nameEnd - nameStart); macroInfo.setIdPos(nameStart, nameEnd - nameStart);
macroInfo.setPos(token.getOffset(), token.getLength()); macroInfo.setPos(startOffset, endOffset - startOffset);
parent.addChild(macro); parent.addChild(macro);
} }
private void parseInclude(CElement parent, Token token) throws CModelException { private void parsePPInclude(CElement parent) throws CModelException, OffsetLimitReachedException {
final String tokenText= token.getText(); int startOffset= fLexer.currentToken().getOffset();
Scanner includeScanner= new Tokenizer(tokenText.toCharArray());
includeScanner.setCurrentPosition(tokenText.indexOf('#') + 1);
int nameStart= 0; int nameStart= 0;
int nameEnd= includeScanner.eofPosition + 1; int nameEnd= 0;
String name= null; String name= null;
boolean isStandard= false; boolean isStandard= false;
Token t= includeScanner.nextToken(); IToken t= nextToken();
if (adaptTokenType(t) == Token.tIDENTIFIER) { switch (t.getType()) {
t= includeScanner.nextToken(); case IToken.tLT:
if (t.type == Token.tLT) { nameStart= fLexer.currentToken().getOffset();
nameStart= includeScanner.getCurrentTokenStartPosition(); do {
do { t= nextToken();
t= includeScanner.nextToken(); } while (t.getType() != IToken.tGT);
} while (t != null && t.type != Token.tGT); nameEnd= fLexer.currentToken().getEndOffset();
nameEnd= includeScanner.getCurrentTokenEndPosition() + 1; name= new String(fLexer.getInputChars(nameStart + 1, nameEnd - 1));
name= tokenText.substring(nameStart + 1, nameEnd - 1); isStandard= true;
} else if (t.type == Token.tSTRING) { break;
nameStart= includeScanner.getCurrentTokenStartPosition(); case IToken.tSTRING:
nameEnd= includeScanner.getCurrentTokenEndPosition() + 1; nameStart= fLexer.currentToken().getOffset();
name= t.getText().substring(1, t.getLength() - 1); nameEnd= fLexer.currentToken().getEndOffset();
isStandard= true; name= t.getImage().substring(1, t.getLength() - 1);
} else if (adaptTokenType(t) == Token.tIDENTIFIER) { break;
nameStart= includeScanner.getCurrentTokenStartPosition(); case IToken.tIDENTIFIER:
nameEnd= includeScanner.getCurrentTokenEndPosition() + 1; nameStart= fLexer.currentToken().getOffset();
name= t.getText(); nameEnd= fLexer.currentToken().getEndOffset();
} name= t.getImage();
break;
default:
} }
if (name == null) { if (name == null) {
return; return;
} }
int endOffset= skipToNewLine();
Include include= new Include(parent, name, isStandard); Include include= new Include(parent, name, isStandard);
SourceManipulationInfo includeInfo= include.getSourceManipulationInfo(); SourceManipulationInfo includeInfo= include.getSourceManipulationInfo();
includeInfo.setIdPos(token.getOffset() + nameStart, nameEnd - nameStart); includeInfo.setIdPos(nameStart, nameEnd - nameStart);
includeInfo.setPos(token.getOffset(), token.getLength()); includeInfo.setPos(startOffset, endOffset - startOffset);
parent.addChild(include); parent.addChild(include);
} }