Adds prototype of debugger

This commit is contained in:
Alexey Andreev 2014-07-25 20:55:36 +04:00
parent 43670ed3ca
commit 71415e71e1
25 changed files with 905 additions and 14 deletions

View File

@ -0,0 +1,26 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.codegen;
/**
*
* @author Alexey Andreev
*/
public interface LocationProvider {
int getLine();
int getColumn();
}

View File

@ -25,14 +25,15 @@ import org.teavm.model.ValueType;
*
* @author Alexey Andreev
*/
public class SourceWriter implements Appendable {
public class SourceWriter implements Appendable, LocationProvider {
private Appendable innerWriter;
private int indentSize;
private NamingStrategy naming;
private boolean lineStart;
private boolean minified;
private int lineWidth;
private int pos;
private int column;
private int line;
SourceWriter(NamingStrategy naming, Appendable innerWriter, int lineWidth) {
this.naming = naming;
@ -64,7 +65,7 @@ public class SourceWriter implements Appendable {
if (value == '\n') {
newLine();
} else {
pos++;
column++;
}
return this;
}
@ -94,7 +95,7 @@ public class SourceWriter implements Appendable {
return;
}
appendIndent();
pos += end - start;
column += end - start;
innerWriter.append(csq, start, end);
}
@ -131,7 +132,7 @@ public class SourceWriter implements Appendable {
if (lineStart) {
for (int i = 0; i < indentSize; ++i) {
innerWriter.append(" ");
pos += 4;
column += 4;
}
lineStart = false;
}
@ -139,25 +140,26 @@ public class SourceWriter implements Appendable {
public SourceWriter newLine() throws IOException{
innerWriter.append('\n');
pos = 0;
column = 0;
++line;
lineStart = true;
return this;
}
public SourceWriter ws() throws IOException {
if (pos >= lineWidth) {
if (column >= lineWidth) {
newLine();
} else {
if (!minified) {
innerWriter.append(' ');
pos++;
column++;
}
}
return this;
}
public SourceWriter tokenBoundary() throws IOException {
if (pos >= lineWidth) {
if (column >= lineWidth) {
newLine();
}
return this;
@ -166,7 +168,7 @@ public class SourceWriter implements Appendable {
public SourceWriter softNewLine() throws IOException{
if (!minified) {
innerWriter.append('\n');
pos = 0;
column = 0;
lineStart = true;
}
return this;
@ -185,4 +187,14 @@ public class SourceWriter implements Appendable {
public NamingStrategy getNaming() {
return naming;
}
@Override
public int getColumn() {
return column;
}
@Override
public int getLine() {
return line;
}
}

View File

@ -0,0 +1,77 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
import java.util.List;
/**
*
* @author Alexey Andreev
*/
public class Breakpoint {
private Debugger debugger;
private List<JavaScriptBreakpoint> jsBreakpoints;
private String fileName;
private int line;
private boolean enabled = true;
Breakpoint(Debugger debugger, List<JavaScriptBreakpoint> jsBreakpoints, String fileName, int line) {
this.debugger = debugger;
this.jsBreakpoints = jsBreakpoints;
this.fileName = fileName;
this.line = line;
for (JavaScriptBreakpoint jsBreakpoint : jsBreakpoints) {
debugger.breakpointMap.put(jsBreakpoint.getId(), this);
}
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
if (this.enabled == enabled) {
return;
}
for (JavaScriptBreakpoint jsBreakpoint : jsBreakpoints) {
jsBreakpoint.setEnabled(enabled);
}
}
public String getFileName() {
return fileName;
}
public int getLine() {
return line;
}
public void destroy() {
for (JavaScriptBreakpoint jsBreakpoint : jsBreakpoints) {
jsBreakpoint.destroy();
debugger.breakpointMap.remove(jsBreakpoint.getId());
}
jsBreakpoints.clear();
}
public boolean isDestroyed() {
return jsBreakpoints.isEmpty();
}
public Debugger getDebugger() {
return debugger;
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
/**
*
* @author Alexey Andreev
*/
public class CallFrame {
private SourceLocation location;
CallFrame(SourceLocation location) {
this.location = location;
}
public SourceLocation getLocation() {
return location;
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
import java.util.*;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class DebugInformation {
List<String> fileNames = new ArrayList<>();
Map<String, Integer> fileNameMap = new HashMap<>();
List<String> classNames = new ArrayList<>();
Map<String, Integer> classNameMap = new HashMap<>();
List<MethodDescriptor> methods = new ArrayList<>();
Map<MethodDescriptor, Integer> methodMap = new HashMap<>();
List<FileDescription> fileDescriptions = new ArrayList<>();
GeneratedLocation[] fileNameKeys;
int[] fileNameValues;
GeneratedLocation[] classKeys;
int[] classValues;
GeneratedLocation[] methodKeys;
int[] methodValues;
GeneratedLocation[] lineNumberKeys;
int[] lineNumberValues;
public Collection<GeneratedLocation> getGeneratedLocations(String fileName, int lineNumber) {
Integer fileIndex = fileNameMap.get(fileName);
if (fileIndex == null) {
return Collections.emptyList();
}
FileDescription description = fileDescriptions.get(lineNumber);
return lineNumber < description.generatedLocations.length ?
Arrays.asList(description.generatedLocations[lineNumber]) :
Collections.<GeneratedLocation>emptyList();
}
public SourceLocation getSourceLocation(int line, int column) {
return getSourceLocation(new GeneratedLocation(line, column));
}
public SourceLocation getSourceLocation(GeneratedLocation generatedLocation) {
String fileName = componentByKey(fileNameKeys, fileNameValues, fileNames, generatedLocation);
String className = componentByKey(classKeys, classValues, classNames, generatedLocation);
MethodDescriptor method = componentByKey(methodKeys, methodValues, methods, generatedLocation);
int lineNumberIndex = indexByKey(lineNumberKeys, generatedLocation);
int lineNumber = lineNumberIndex >= 0 ? lineNumberValues[lineNumberIndex] : -1;
return new SourceLocation(fileName, lineNumber, new MethodReference(className, method));
}
private <T> T componentByKey(GeneratedLocation[] keys, int[] valueIndexes, List<T> values,
GeneratedLocation location) {
int keyIndex = indexByKey(keys, location);
int valueIndex = keyIndex >= 0 ? valueIndexes[keyIndex] : -1;
return valueIndex >= 0 ? values.get(valueIndex) : null;
}
private int indexByKey(GeneratedLocation[] keys, GeneratedLocation location) {
int index = Arrays.binarySearch(keys, location);
return index >= 0 ? index : -index - 2;
}
class FileDescription {
GeneratedLocation[][] generatedLocations;
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
import org.teavm.codegen.LocationProvider;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class DebugInformationBuilder implements DebugInformationEmitter {
private LocationProvider locationProvider;
public LocationProvider getLocationProvider() {
return locationProvider;
}
public void setLocationProvider(LocationProvider locationProvider) {
this.locationProvider = locationProvider;
}
@Override
public void emitFile(String fileName) {
}
@Override
public void emitMethod(MethodReference method) {
}
@Override
public void emitLineNumber(String lineNumber) {
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public interface DebugInformationEmitter {
void emitFile(String fileName);
void emitMethod(MethodReference method);
void emitLineNumber(String lineNumber);
}

View File

@ -0,0 +1,148 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
import java.util.*;
/**
*
* @author Alexey Andreev
*/
// TODO: variable name handling
// TODO: class fields handling
public class Debugger {
private List<DebuggerListener> listeners = new ArrayList<>();
private JavaScriptDebugger javaScriptDebugger;
private DebugInformation debugInformation;
private List<JavaScriptBreakpoint> temporaryJsBreakpoints = new ArrayList<>();
Map<String, Breakpoint> breakpointMap = new HashMap<>();
private CallFrame[] callStack;
public Debugger(JavaScriptDebugger javaScriptDebugger, DebugInformation debugInformation) {
this.javaScriptDebugger = javaScriptDebugger;
this.debugInformation = debugInformation;
javaScriptDebugger.addListener(javaScriptListener);
}
public void addListener(DebuggerListener listener) {
listeners.add(listener);
}
public void removeListener(DebuggerListener listener) {
listeners.remove(listener);
}
public void suspend() {
javaScriptDebugger.suspend();
}
public void resume() {
javaScriptDebugger.resume();
}
public void stepInto() {
if (!javaScriptDebugger.isSuspended()) {
return;
}
javaScriptDebugger.stepInto();
}
public void stepOut() {
if (!javaScriptDebugger.isSuspended()) {
return;
}
// TODO: lookup all locations that are "out of" the current location and create temporary breakpoints
}
public void stepOver() {
if (!javaScriptDebugger.isSuspended()) {
return;
}
// TODO: lookup all locations that are "after" the current location and create temporary breakpoints
}
public void continueToLocation(String fileName, int line) {
if (!javaScriptDebugger.isSuspended()) {
return;
}
Collection<GeneratedLocation> locations = debugInformation.getGeneratedLocations(fileName, line);
for (GeneratedLocation location : locations) {
JavaScriptBreakpoint jsBreakpoint = javaScriptDebugger.createBreakpoint(location);
if (jsBreakpoint != null) {
temporaryJsBreakpoints.add(jsBreakpoint);
}
}
javaScriptDebugger.resume();
}
public boolean isSuspended() {
return javaScriptDebugger.isSuspended();
}
public Breakpoint createBreakpoint(String fileName, int line) {
Collection<GeneratedLocation> locations = debugInformation.getGeneratedLocations(fileName, line);
List<JavaScriptBreakpoint> jsBreakpoints = new ArrayList<>();
for (GeneratedLocation location : locations) {
JavaScriptBreakpoint jsBreakpoint = javaScriptDebugger.createBreakpoint(location);
if (jsBreakpoint != null) {
jsBreakpoints.add(jsBreakpoint);
}
}
return !jsBreakpoints.isEmpty() ? new Breakpoint(this, jsBreakpoints, fileName, line) : null;
}
public CallFrame[] getCallStack() {
if (isSuspended()) {
return null;
}
if (callStack == null) {
// TODO: with inlining enabled we can have several JVM methods compiled into one JavaScript function
// so we must consider this case.
List<CallFrame> frames = new ArrayList<>();
boolean wasEmpty = false;
for (JavaScriptCallFrame jsFrame : javaScriptDebugger.getCallStack()) {
SourceLocation loc = debugInformation.getSourceLocation(jsFrame.getLocation());
boolean empty = loc.getFileName() != null || loc.getMethod() != null || loc.getLine() < 0;
if (!empty || !wasEmpty) {
frames.add(new CallFrame(loc));
}
wasEmpty = empty;
}
callStack = frames.toArray(new CallFrame[0]);
}
return callStack.clone();
}
private JavaScriptDebuggerListener javaScriptListener = new JavaScriptDebuggerListener() {
@Override
public void resumed() {
for (JavaScriptBreakpoint jsBreakpoint : temporaryJsBreakpoints) {
jsBreakpoint.destroy();
}
temporaryJsBreakpoints.clear();
for (DebuggerListener listener : listeners) {
listener.resumed();
}
}
@Override
public void paused() {
for (DebuggerListener listener : listeners) {
listener.paused();
}
}
};
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
/**
*
* @author Alexey Andreev
*/
public interface DebuggerListener {
void resumed();
void paused();
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class DummyDebugInformationEmitter implements DebugInformationEmitter {
@Override
public void emitFile(String fileName) {
}
@Override
public void emitMethod(MethodReference method) {
}
@Override
public void emitLineNumber(String lineNumber) {
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
/**
*
* @author Alexey Andreev
*/
public class GeneratedLocation implements Comparable<GeneratedLocation> {
private int line;
private int column;
public GeneratedLocation(int line, int column) {
this.line = line;
this.column = column;
}
public int getLine() {
return line;
}
public int getColumn() {
return column;
}
@Override
public int compareTo(GeneratedLocation o) {
int r = Integer.compare(line, o.line);
if (r == 0) {
r = Integer.compare(column, o.column);
}
return r;
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
/**
*
* @author Alexey Andreev
*/
public interface JavaScriptBreakpoint {
boolean isEnabled();
void setEnabled(boolean enabled);
String getId();
String getFileName();
GeneratedLocation getLocation();
void destroy();
}

View File

@ -0,0 +1,24 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
/**
*
* @author Alexey Andreev
*/
public interface JavaScriptCallFrame {
GeneratedLocation getLocation();
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
/**
*
* @author Alexey Andreev
*/
public interface JavaScriptDebugger {
void addListener(JavaScriptDebuggerListener listener);
void removeListener(JavaScriptDebuggerListener listener);
void suspend();
void resume();
void stepInto();
void stepOut();
void stepOver();
void continueToLocation(GeneratedLocation location);
boolean isSuspended();
JavaScriptCallFrame[] getCallStack();
JavaScriptBreakpoint getCurrentBreakpoint();
JavaScriptBreakpoint createBreakpoint(GeneratedLocation location);
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
/**
*
* @author Alexey Andreev
*/
public interface JavaScriptDebuggerListener {
void paused();
void resumed();
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.debugging;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class SourceLocation {
private String fileName;
private int line;
private MethodReference method;
public SourceLocation(String fileName, int line, MethodReference method) {
this.fileName = fileName;
this.line = line;
this.method = method;
}
public String getFileName() {
return fileName;
}
public int getLine() {
return line;
}
public MethodReference getMethod() {
return method;
}
}

View File

@ -1,12 +1,12 @@
/*
* Copyright 2011 Alexey Andreev.
*
*
* 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.
@ -16,12 +16,13 @@
package org.teavm.javascript.ast;
/**
*
*
* @author Alexey Andreev
*/
public class AssignmentStatement extends Statement {
private Expr leftValue;
private Expr rightValue;
private NodeLocation location;
public Expr getLeftValue() {
return leftValue;
@ -39,6 +40,14 @@ public class AssignmentStatement extends Statement {
this.rightValue = rightValue;
}
public NodeLocation getLocation() {
return location;
}
public void setLocation(NodeLocation location) {
this.location = location;
}
@Override
public void acceptVisitor(StatementVisitor visitor) {
visitor.visit(this);

View File

@ -21,6 +21,7 @@ package org.teavm.javascript.ast;
*/
public class BreakStatement extends Statement {
private IdentifiedStatement target;
private NodeLocation location;
public IdentifiedStatement getTarget() {
return target;
@ -30,6 +31,14 @@ public class BreakStatement extends Statement {
this.target = target;
}
public NodeLocation getLocation() {
return location;
}
public void setLocation(NodeLocation location) {
this.location = location;
}
@Override
public void acceptVisitor(StatementVisitor visitor) {
visitor.visit(this);

View File

@ -21,6 +21,7 @@ package org.teavm.javascript.ast;
*/
public class ContinueStatement extends Statement {
private IdentifiedStatement target;
private NodeLocation location;
public IdentifiedStatement getTarget() {
return target;
@ -30,6 +31,14 @@ public class ContinueStatement extends Statement {
this.target = target;
}
public NodeLocation getLocation() {
return location;
}
public void setLocation(NodeLocation location) {
this.location = location;
}
@Override
public void acceptVisitor(StatementVisitor visitor) {
visitor.visit(this);

View File

@ -25,6 +25,8 @@ import org.teavm.model.*;
* @author Alexey Andreev
*/
public abstract class Expr implements Cloneable {
private NodeLocation location;
public abstract void acceptVisitor(ExprVisitor visitor);
@Override
@ -148,4 +150,12 @@ public abstract class Expr implements Cloneable {
expr.setType(type);
return expr;
}
public NodeLocation getLocation() {
return location;
}
public void setLocation(NodeLocation location) {
this.location = location;
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.javascript.ast;
import org.teavm.model.MethodDescriptor;
/**
*
* @author Alexey Andreev
*/
public class NodeLocation {
private String className;
private MethodDescriptor method;
private int lineNumber;
public NodeLocation(String className, MethodDescriptor method, int lineNumber) {
this.className = className;
this.method = method;
this.lineNumber = lineNumber;
}
public String getClassName() {
return className;
}
public MethodDescriptor getMethod() {
return method;
}
public int getLineNumber() {
return lineNumber;
}
}

View File

@ -21,6 +21,7 @@ package org.teavm.javascript.ast;
*/
public class ReturnStatement extends Statement {
private Expr result;
private NodeLocation location;
public Expr getResult() {
return result;
@ -30,6 +31,14 @@ public class ReturnStatement extends Statement {
this.result = result;
}
public NodeLocation getLocation() {
return location;
}
public void setLocation(NodeLocation location) {
this.location = location;
}
@Override
public void acceptVisitor(StatementVisitor visitor) {
visitor.visit(this);

View File

@ -21,6 +21,7 @@ package org.teavm.javascript.ast;
*/
public class ThrowStatement extends Statement {
private Expr exception;
private NodeLocation location;
public Expr getException() {
return exception;
@ -30,6 +31,14 @@ public class ThrowStatement extends Statement {
this.exception = exception;
}
public NodeLocation getLocation() {
return location;
}
public void setLocation(NodeLocation location) {
this.location = location;
}
@Override
public void acceptVisitor(StatementVisitor visitor) {
visitor.visit(this);

View File

@ -23,6 +23,7 @@ import org.teavm.model.instructions.InstructionVisitor;
*/
public abstract class Instruction {
private BasicBlock basicBlock;
private InstructionLocation location;
void setBasicBlock(BasicBlock basicBlock) {
this.basicBlock = basicBlock;
@ -36,5 +37,13 @@ public abstract class Instruction {
return basicBlock != null ? basicBlock.getProgram() : null;
}
public InstructionLocation getLocation() {
return location;
}
public void setLocation(InstructionLocation location) {
this.location = location;
}
public abstract void acceptVisitor(InstructionVisitor visitor);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.model;
/**
*
* @author Alexey Andreev
*/
public class InstructionLocation {
private String className;
private MethodDescriptor method;
private int lineNumber = -1;
public String getClassName() {
return className;
}
public MethodDescriptor getMethod() {
return method;
}
public int getLineNumber() {
return lineNumber;
}
}