Created
July 30, 2010 20:45
-
-
Save ashigeru/501282 to your computer and use it in GitHub Desktop.
Eclipseのコンパイラに介入するプログラムスタブ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2010 @ashigeru. | |
* | |
* 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 com.ashigeru.example.javaex.core; | |
import java.util.List; | |
import org.eclipse.core.resources.IFile; | |
import org.eclipse.jdt.core.ICompilationUnit; | |
import org.eclipse.jdt.core.IJavaProject; | |
import org.eclipse.jdt.core.JavaCore; | |
import org.eclipse.jdt.core.JavaModelException; | |
import org.eclipse.jdt.core.compiler.BuildContext; | |
import org.eclipse.jdt.core.compiler.CompilationParticipant; | |
import org.eclipse.jdt.core.compiler.ReconcileContext; | |
import org.eclipse.jdt.core.dom.AST; | |
import org.eclipse.jdt.core.dom.ASTParser; | |
import org.eclipse.jdt.core.dom.CompilationUnit; | |
/** | |
* Eclipse JDTのコンパイルフェーズに参加する。 | |
*/ | |
public class MyCompilationParticipant extends CompilationParticipant { | |
@Override | |
public boolean isActive(IJavaProject project) { | |
return true; | |
} | |
@Override | |
public void reconcile(ReconcileContext context) { | |
CompilationUnit ast; | |
try { | |
ast = context.getAST3(); | |
if (ast == null) { | |
return; | |
} | |
} | |
catch (JavaModelException e) { | |
return; | |
} | |
String fileName = context.getWorkingCopy().getElementName(); | |
List<MyProblem> problems = verify(fileName, ast); | |
context.putProblems( | |
MyProblem.MARKER_ID, | |
problems.toArray(new MyProblem[problems.size()])); | |
} | |
@Override | |
public void buildStarting(BuildContext[] files, boolean isBatch) { | |
for (BuildContext context : files) { | |
String fileNAme = context.getFile().getName(); | |
CompilationUnit ast = parse(context.getFile()); | |
List<MyProblem> problems = verify(fileNAme, ast); | |
context.recordNewProblems( | |
problems.toArray(new MyProblem[problems.size()])); | |
} | |
} | |
CompilationUnit parse(IFile file) { | |
ICompilationUnit cu = JavaCore.createCompilationUnitFrom(file); | |
ASTParser parser = ASTParser.newParser(AST.JLS3); | |
parser.setSource(cu); | |
parser.setResolveBindings(true); | |
CompilationUnit ast = (CompilationUnit) parser.createAST(null); | |
return ast; | |
} | |
List<MyProblem> verify(String fileName, CompilationUnit ast) { | |
MyVerifier verifier = new MyVerifier(fileName, ast); | |
return verifier.verify(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2010 @ashigeru. | |
* | |
* 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 com.ashigeru.example.javaex.core; | |
import org.eclipse.jdt.core.compiler.CategorizedProblem; | |
import org.eclipse.jdt.core.compiler.IProblem; | |
/** | |
* 問題情報を表すモデル。 | |
*/ | |
public class MyProblem extends CategorizedProblem { | |
/** | |
* 対象となるマーカーの識別子。 | |
*/ | |
public static final String MARKER_ID = "com.ashigeru.example.javaex.problem"; | |
/** | |
* 問題の種類。 | |
*/ | |
public enum Kind { | |
/** | |
* 致命的な問題。 | |
*/ | |
ERROR, | |
/** | |
* 警告レベルの問題。 | |
*/ | |
WARNING, | |
} | |
private Kind kind; | |
private String message; | |
private String fileName; | |
private int sourceStart; | |
private int sourceEnd; | |
private int lineNumber; | |
/** | |
* インスタンスを生成する。 | |
* @param kind 問題の種類 | |
* @param message メッセージ | |
* @param fileName ファイル名 | |
*/ | |
public MyProblem(Kind kind, String message, String fileName) { | |
this.kind = kind; | |
this.message = message; | |
this.fileName = fileName; | |
} | |
@Override | |
public int getCategoryID() { | |
return CategorizedProblem.CAT_UNSPECIFIED; | |
} | |
@Override | |
public String getMarkerType() { | |
return MARKER_ID; | |
} | |
public String[] getArguments() { | |
return new String[0]; | |
} | |
public int getID() { | |
return IProblem.ExternalProblemNotFixable; | |
} | |
public String getMessage() { | |
return message; | |
} | |
public char[] getOriginatingFileName() { | |
return fileName.toCharArray(); | |
} | |
public boolean isError() { | |
return kind == Kind.ERROR; | |
} | |
public boolean isWarning() { | |
return kind == Kind.WARNING; | |
} | |
public int getSourceStart() { | |
return sourceStart; | |
} | |
public int getSourceEnd() { | |
return sourceEnd; | |
} | |
public int getSourceLineNumber() { | |
return lineNumber; | |
} | |
public void setSourceStart(int sourceStart) { | |
this.sourceStart = sourceStart; | |
} | |
public void setSourceEnd(int sourceEnd) { | |
this.sourceEnd = sourceEnd; | |
} | |
public void setSourceLineNumber(int lineNumber) { | |
this.lineNumber = lineNumber; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2010 @ashigeru. | |
* | |
* 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 com.ashigeru.example.javaex.core; | |
import java.util.ArrayList; | |
import java.util.List; | |
import org.eclipse.jdt.core.dom.ASTNode; | |
import org.eclipse.jdt.core.dom.ASTVisitor; | |
import org.eclipse.jdt.core.dom.CompilationUnit; | |
import org.eclipse.jdt.core.dom.MethodDeclaration; | |
import org.eclipse.jdt.core.dom.SimpleName; | |
import com.ashigeru.example.javaex.core.MyProblem.Kind; | |
/** | |
* Javaのプログラムを検証する。 | |
*/ | |
public class MyVerifier { | |
final String fileName; | |
final CompilationUnit root; | |
/** | |
* インスタンスを生成する。 | |
* @param fileName 対象のファイルパス | |
* @param compilationUnit 対象のコンパイル単位 | |
*/ | |
public MyVerifier(String fileName, CompilationUnit compilationUnit) { | |
this.fileName = fileName; | |
this.root = compilationUnit; | |
} | |
/** | |
* このオブジェクトが対象とするプログラムを検証し、検出した問題の一覧を返す。 | |
* @return 検出した問題の一覧 | |
*/ | |
public List<MyProblem> verify() { | |
Engine engine = new Engine(); | |
root.accept(engine); | |
return engine.problems; | |
} | |
/** | |
* 検証器の本体。 | |
*/ | |
class Engine extends ASTVisitor { | |
// FIXME 検証プログラム | |
@Override | |
public boolean visit(MethodDeclaration node) { | |
SimpleName name = node.getName(); | |
if (name.getIdentifier().startsWith("error")) { | |
report( | |
Kind.ERROR, | |
"errorメソッドを発見", | |
name, | |
0, | |
name.getLength()); | |
} | |
return true; | |
} | |
List<MyProblem> problems = new ArrayList<MyProblem>(); | |
/** | |
* 現在のセッションに指定の問題情報を追加する。 | |
* @param kind 問題の種類 | |
* @param message メッセージ | |
* @param node 問題が発生したノード | |
* @param offset 問題発生位置の、ノードから見たテキストオフセット | |
* @param length 問題発生位置からのテキストの長さ | |
*/ | |
void report( | |
Kind kind, | |
String message, | |
ASTNode node, | |
int offset, | |
int length) { | |
MyProblem prom = new MyProblem(kind, message, fileName); | |
int start = node.getStartPosition() + offset; | |
int end = start + length; | |
prom.setSourceStart(start); | |
prom.setSourceEnd(end - 1); | |
prom.setSourceLineNumber(root.getLineNumber(start)); | |
problems.add(prom); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment