mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 16:58:56 +00:00
Some improvements and normalization of debug information.
This commit is contained in:
parent
a2945fc474
commit
70c41e25ee
2 changed files with 225 additions and 18 deletions
|
@ -7,13 +7,21 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.generator.trace;
|
||||
|
||||
import static com.google.common.collect.Lists.*;
|
||||
import static com.google.common.collect.Maps.*;
|
||||
import static com.google.common.collect.Sets.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.xtext.LanguageInfo;
|
||||
|
@ -30,55 +38,105 @@ import com.google.inject.Inject;
|
|||
*/
|
||||
public class SmapSupport {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final Logger log = Logger.getLogger(SmapSupport.class);
|
||||
|
||||
@Inject private IResourceServiceProvider.Registry serviceProviderRegistry;
|
||||
|
||||
public String generateSmap(AbstractTraceRegion rootTraceRegion, String outputFileName) {
|
||||
final Set<LineMapping> lineData = newLinkedHashSet();
|
||||
createSmapInfo(rootTraceRegion, lineData, -1);
|
||||
List<LineMapping> lineInfo = normalizeLineInfo(lineData);
|
||||
|
||||
return toSmap(outputFileName, lineInfo);
|
||||
}
|
||||
|
||||
protected String toSmap(String outputFileName, List<LineMapping> lineInfo) {
|
||||
SmapGenerator generator = new SmapGenerator();
|
||||
generator.setOutputFileName(outputFileName);
|
||||
Map<String,SmapStratum> strata = newHashMap();
|
||||
createSmapInfo(rootTraceRegion, strata, -1);
|
||||
|
||||
for (SmapStratum stratum : strata.values()) {
|
||||
generator.addStratum(stratum, true);
|
||||
for (LineMapping lm : lineInfo) {
|
||||
String stratumName = getStratumName(lm.source);
|
||||
SmapStratum stratum = strata.get(stratumName);
|
||||
if (stratum == null) {
|
||||
stratum = new SmapStratum(stratumName);
|
||||
strata.put(stratumName, stratum);
|
||||
generator.addStratum(stratum, true);
|
||||
}
|
||||
final String path = getPath(lm.source);
|
||||
final String fileName = lm.source.lastSegment();
|
||||
stratum.addFile(fileName, path);
|
||||
stratum.addLineData(lm.sourceStartLine, fileName, 1, lm.targetStartLine+1, lm.targetEndLine - lm.targetStartLine + 1);
|
||||
}
|
||||
return generator.getString();
|
||||
}
|
||||
|
||||
public void createSmapInfo(AbstractTraceRegion targetRegion, Map<String,SmapStratum> strata, int mappedLine) {
|
||||
public List<LineMapping> normalizeLineInfo(Set<LineMapping> lineData) {
|
||||
ArrayList<LineMapping> list = newArrayList(lineData);
|
||||
Collections.sort(list, new Comparator<LineMapping>() {
|
||||
public int compare(LineMapping o1, LineMapping o2) {
|
||||
int compareResult = o2.targetStartLine - o1.targetStartLine;
|
||||
if (compareResult == 0) {
|
||||
return o2.targetEndLine - o1.targetEndLine;
|
||||
}
|
||||
return compareResult;
|
||||
}
|
||||
});
|
||||
List<LineMapping> result = newLinkedList();
|
||||
LineMapping current = null;
|
||||
for (LineMapping mapping : list) {
|
||||
if (current != null
|
||||
&& current.sourceStartLine == mapping.sourceStartLine
|
||||
&& current.source.equals(mapping.source)) {
|
||||
|
||||
current.targetStartLine = mapping.targetStartLine;
|
||||
} else {
|
||||
int lastLine = mapping.targetEndLine;
|
||||
if (current != null) {
|
||||
lastLine = current.targetStartLine-1;
|
||||
result.add(0,current);
|
||||
}
|
||||
if (lastLine < mapping.targetStartLine) {
|
||||
lastLine = mapping.targetStartLine;
|
||||
}
|
||||
current = new LineMapping(mapping.sourceStartLine, mapping.targetStartLine, lastLine, mapping.source);
|
||||
}
|
||||
}
|
||||
result.add(0, current);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void createSmapInfo(AbstractTraceRegion targetRegion, Set<LineMapping> lineMappings, int mappedLine) {
|
||||
if (mappedLine == targetRegion.getMyLineNumber()) {
|
||||
if (mappedLine == targetRegion.getMyEndLineNumber())
|
||||
return; //SKIP
|
||||
for (AbstractTraceRegion nested: targetRegion.getNestedRegions()) {
|
||||
createSmapInfo(nested, strata, mappedLine);
|
||||
createSmapInfo(nested, lineMappings, mappedLine);
|
||||
}
|
||||
}
|
||||
ILocationData location = targetRegion.getMergedAssociatedLocation();
|
||||
if (location != null) {
|
||||
final URI path = targetRegion.getAssociatedPath();
|
||||
if (path != null) {
|
||||
final String fileName = path.trimFragment().lastSegment();
|
||||
SmapStratum stratum = strata.get(fileName);
|
||||
if (stratum == null) {
|
||||
IResourceServiceProvider provider = serviceProviderRegistry.getResourceServiceProvider(path.trimFragment());
|
||||
String name = provider.get(LanguageInfo.class).getShortName();
|
||||
stratum = new SmapStratum(name);
|
||||
strata.put(fileName, stratum);
|
||||
}
|
||||
stratum.addFile(fileName, getPath(path));
|
||||
stratum.addLineData(location.getLineNumber()+1, fileName, 1, targetRegion.getMyLineNumber()+1, 1);
|
||||
lineMappings.add(new LineMapping(location.getLineNumber()+1, targetRegion.getMyLineNumber(), targetRegion.getMyEndLineNumber(), path));
|
||||
}
|
||||
}
|
||||
if (targetRegion.getMyLineNumber() != targetRegion.getMyEndLineNumber()) {
|
||||
for (AbstractTraceRegion nested: targetRegion.getNestedRegions()) {
|
||||
createSmapInfo(nested, strata, targetRegion.getMyLineNumber());
|
||||
createSmapInfo(nested, lineMappings, targetRegion.getMyLineNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String getStratumName(final URI path) {
|
||||
IResourceServiceProvider provider = serviceProviderRegistry.getResourceServiceProvider(path.trimFragment());
|
||||
String name = provider.get(LanguageInfo.class).getShortName();
|
||||
return name;
|
||||
}
|
||||
|
||||
protected String getPath(URI path) {
|
||||
String fullPath = path.trimFragment().toPlatformString(true);
|
||||
final String substring = fullPath.substring(fullPath.substring(1).indexOf('/')+1);
|
||||
System.out.println(substring);
|
||||
return substring;
|
||||
}
|
||||
|
||||
|
@ -92,4 +150,59 @@ public class SmapSupport {
|
|||
return newByteCode;
|
||||
}
|
||||
|
||||
public static class LineMapping {
|
||||
|
||||
public int sourceStartLine,
|
||||
targetStartLine,
|
||||
targetEndLine;
|
||||
public URI source;
|
||||
public LineMapping(int sourceStartLine, int targetStartLine, int targetEndLine,
|
||||
URI source) {
|
||||
this.sourceStartLine = sourceStartLine;
|
||||
this.targetStartLine = targetStartLine;
|
||||
this.targetEndLine = targetEndLine;
|
||||
this.source = source;
|
||||
if (sourceStartLine < 0 || targetStartLine < 0 || targetEndLine <0 || targetStartLine>targetEndLine || source == null)
|
||||
throw new IllegalArgumentException(toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((source == null) ? 0 : source.hashCode());
|
||||
result = prime * result + sourceStartLine;
|
||||
result = prime * result + targetEndLine;
|
||||
result = prime * result + targetStartLine;
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
LineMapping other = (LineMapping) obj;
|
||||
if (source == null) {
|
||||
if (other.source != null)
|
||||
return false;
|
||||
} else if (!source.equals(other.source))
|
||||
return false;
|
||||
if (sourceStartLine != other.sourceStartLine)
|
||||
return false;
|
||||
if (targetEndLine != other.targetEndLine)
|
||||
return false;
|
||||
if (targetStartLine != other.targetStartLine)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LineMapping [sourceStartLine=" + sourceStartLine + ", targetStartLine=" + targetStartLine
|
||||
+ ", targetEndLine=" + targetEndLine + ", source=" + source + "]";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012 itemis AG (http://www.itemis.eu) and others.
|
||||
* 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
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.generator.trace;
|
||||
|
||||
import static com.google.common.collect.Sets.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.xtext.generator.trace.SmapSupport.LineMapping;
|
||||
import org.junit.Test;
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*/
|
||||
public class SmapSupportTest {
|
||||
|
||||
private URI source = URI.createURI("fake://source.dsl");
|
||||
|
||||
private SmapSupport support = new SmapSupport() {
|
||||
@Override
|
||||
protected String getStratumName(URI path) {
|
||||
return "myLang";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPath(URI path) {
|
||||
return "source.dsl";
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testNomalization() {
|
||||
Set<LineMapping> mappings = newHashSet(
|
||||
new LineMapping(1,1,1,source),
|
||||
new LineMapping(2,5,5,source),
|
||||
new LineMapping(1,6,6,source),
|
||||
new LineMapping(3,7,8,source),
|
||||
new LineMapping(3,8,8,source));
|
||||
List<LineMapping> info = support.normalizeLineInfo(mappings);
|
||||
assertEquals(info.toString(), 4, info.size());
|
||||
|
||||
assertEquals(1, info.get(0).sourceStartLine);
|
||||
assertEquals(1, info.get(0).targetStartLine);
|
||||
assertEquals(4, info.get(0).targetEndLine);
|
||||
|
||||
assertEquals(2, info.get(1).sourceStartLine);
|
||||
assertEquals(5, info.get(1).targetStartLine);
|
||||
assertEquals(5, info.get(1).targetEndLine);
|
||||
|
||||
assertEquals(1, info.get(2).sourceStartLine);
|
||||
assertEquals(6, info.get(2).targetStartLine);
|
||||
assertEquals(6, info.get(2).targetEndLine);
|
||||
|
||||
assertEquals(3, info.get(3).sourceStartLine);
|
||||
assertEquals(7, info.get(3).targetStartLine);
|
||||
assertEquals(8, info.get(3).targetEndLine);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNomalizeOverlaps() {
|
||||
Set<LineMapping> mappings = newHashSet(
|
||||
new LineMapping(1,1,8,source),
|
||||
new LineMapping(2,5,8,source),
|
||||
new LineMapping(1,6,6,source),
|
||||
new LineMapping(3,7,8,source),
|
||||
new LineMapping(3,8,8,source));
|
||||
List<LineMapping> info = support.normalizeLineInfo(mappings);
|
||||
assertEquals(info.toString(), 4, info.size());
|
||||
|
||||
assertEquals(1, info.get(0).sourceStartLine);
|
||||
assertEquals(1, info.get(0).targetStartLine);
|
||||
assertEquals(4, info.get(0).targetEndLine);
|
||||
|
||||
assertEquals(2, info.get(1).sourceStartLine);
|
||||
assertEquals(5, info.get(1).targetStartLine);
|
||||
assertEquals(5, info.get(1).targetEndLine);
|
||||
|
||||
assertEquals(1, info.get(2).sourceStartLine);
|
||||
assertEquals(6, info.get(2).targetStartLine);
|
||||
assertEquals(6, info.get(2).targetEndLine);
|
||||
|
||||
assertEquals(3, info.get(3).sourceStartLine);
|
||||
assertEquals(7, info.get(3).targetStartLine);
|
||||
assertEquals(8, info.get(3).targetEndLine);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue