mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-21 11:31:43 +00:00
GT-113_emteere Adding initial SleighEditor to public version.
This commit is contained in:
parent
dd15435371
commit
1779fdd94d
6
.gitignore
vendored
6
.gitignore
vendored
@ -62,3 +62,9 @@ Release
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
|
||||
# Ignore XTEXT generated dirs/files
|
||||
*/*/*/*/xtend-gen
|
||||
*/*/*/*/src-gen
|
||||
*/*/*/*/model/generated
|
||||
*/*/*/*/test-bin
|
||||
|
@ -0,0 +1,42 @@
|
||||
##VERSION: 2.0
|
||||
##MODULE IP: BSD
|
||||
##MODULE IP: Eclipse Public License 1.0
|
||||
ghidra.xtext.sleigh.feature/build.properties||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.feature/category.xml||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.feature/feature.xml||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ide/META-INF/MANIFEST.MF||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ide/build.properties||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ide/src/ghidra/xtext/sleigh/ide/SleighIdeModule.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ide/src/ghidra/xtext/sleigh/ide/SleighIdeSetup.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.tests/META-INF/MANIFEST.MF||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.tests/build.properties||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.tests/src/ghidra/xtext/sleigh/tests/CrossReferenceTest.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.tests/src/ghidra/xtext/sleigh/tests/SleighMacroTest.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.tests/src/ghidra/xtext/sleigh/tests/SleighParsingTest.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.tests/src/ghidra/xtext/sleigh/tests/SleighScopeTest.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui.tests/META-INF/MANIFEST.MF||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui.tests/build.properties||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/META-INF/MANIFEST.MF||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/build.properties||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/plugin.xml||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/src/ghidra/xtext/sleigh/ui/SleighEObjectHoverProvider.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/src/ghidra/xtext/sleigh/ui/SleighTextEditComposer.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/src/ghidra/xtext/sleigh/ui/SleighUiModule.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/src/ghidra/xtext/sleigh/ui/contentassist/SleighProposalProvider.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/src/ghidra/xtext/sleigh/ui/labeling/SleighDescriptionLabelProvider.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/src/ghidra/xtext/sleigh/ui/labeling/SleighLabelProvider.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/src/ghidra/xtext/sleigh/ui/outline/SleighOutlineTreeProvider.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh.ui/src/ghidra/xtext/sleigh/ui/quickfix/SleighQuickfixProvider.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/.launch/Generate Sleigh (sleigh) Language Infrastructure.launch||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/.launch/Launch Runtime Eclipse.launch||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/META-INF/MANIFEST.MF||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/build.properties||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/plugin.xml||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/src/ghidra/xtext/sleigh/GenerateSleigh.mwe2||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/src/ghidra/xtext/sleigh/Sleigh.xtext||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/src/ghidra/xtext/sleigh/SleighRuntimeModule.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/src/ghidra/xtext/sleigh/SleighStandaloneSetup.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/src/ghidra/xtext/sleigh/formatting2/SleighFormatter.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/src/ghidra/xtext/sleigh/generator/SleighGenerator.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/src/ghidra/xtext/sleigh/scoping/SleighScopeProvider.xtend||GHIDRA||||END|
|
||||
ghidra.xtext.sleigh/src/ghidra/xtext/sleigh/validation/SleighValidator.xtend||GHIDRA||||END|
|
@ -0,0 +1,2 @@
|
||||
bin.includes = feature.xml,\
|
||||
category.xml
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<site>
|
||||
<feature url="features/ghidra.xtext.sleigh.feature_1.0.0.qualifier.jar" id="ghidra.xtext.sleigh.feature" version="1.0.0.qualifier">
|
||||
<category name="ghidra.xtext.sleigh.editor"/>
|
||||
</feature>
|
||||
<category-def name="ghidra.xtext.sleigh.editor" label="Sleigh Editor"/>
|
||||
</site>
|
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feature
|
||||
id="ghidra.xtext.sleigh.feature"
|
||||
label="Ghidra Sleigh Editor"
|
||||
version="1.0.0.qualifier"
|
||||
provider-name="Ghidra">
|
||||
|
||||
<license url="">
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
</license>
|
||||
|
||||
<requires>
|
||||
<import plugin="org.eclipse.xtext"/>
|
||||
<import plugin="org.eclipse.xtext.xbase"/>
|
||||
<import plugin="org.eclipse.xtext.ide"/>
|
||||
<import plugin="org.eclipse.xtext.xbase.ide"/>
|
||||
<import plugin="org.eclipse.xtext.ui"/>
|
||||
<import plugin="org.eclipse.xtext.builder"/>
|
||||
</requires>
|
||||
|
||||
<plugin
|
||||
id="ghidra.xtext.sleigh"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="ghidra.xtext.sleigh.ide"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="ghidra.xtext.sleigh.ui"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
</feature>
|
@ -0,0 +1,15 @@
|
||||
Manifest-Version: 1.0
|
||||
Automatic-Module-Name: ghidra.xtext.sleigh.ide
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: ghidra.xtext.sleigh.ide
|
||||
Bundle-Vendor: My Company
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-SymbolicName: ghidra.xtext.sleigh.ide; singleton:=true
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: ghidra.xtext.sleigh,
|
||||
org.eclipse.xtext.ide,
|
||||
org.eclipse.xtext.xbase.ide,
|
||||
org.antlr.runtime;bundle-version="[3.2.0,3.2.1)"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||
Export-Package: ghidra.xtext.sleigh.ide.contentassist.antlr,
|
||||
ghidra.xtext.sleigh.ide.contentassist.antlr.internal
|
@ -0,0 +1,6 @@
|
||||
source.. = src/,\
|
||||
src-gen/,\
|
||||
xtend-gen/
|
||||
bin.includes = .,\
|
||||
META-INF/
|
||||
bin.excludes = **/*.xtend
|
@ -0,0 +1,23 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ide
|
||||
|
||||
|
||||
/**
|
||||
* Use this class to register ide components.
|
||||
*/
|
||||
class SleighIdeModule extends AbstractSleighIdeModule {
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ide
|
||||
|
||||
import com.google.inject.Guice
|
||||
import ghidra.xtext.sleigh.SleighRuntimeModule
|
||||
import ghidra.xtext.sleigh.SleighStandaloneSetup
|
||||
import org.eclipse.xtext.util.Modules2
|
||||
|
||||
/**
|
||||
* Initialization support for running Xtext languages as language servers.
|
||||
*/
|
||||
class SleighIdeSetup extends SleighStandaloneSetup {
|
||||
|
||||
override createInjector() {
|
||||
Guice.createInjector(Modules2.mixin(new SleighRuntimeModule, new SleighIdeModule))
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
Manifest-Version: 1.0
|
||||
Automatic-Module-Name: ghidra.xtext.sleigh.tests
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: ghidra.xtext.sleigh.tests
|
||||
Bundle-Vendor: My Company
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-SymbolicName: ghidra.xtext.sleigh.tests; singleton:=true
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: ghidra.xtext.sleigh,
|
||||
org.junit.jupiter.api;bundle-version="[5.0.0,6.0.0)",
|
||||
org.eclipse.xtext.testing,
|
||||
org.eclipse.xtext.xbase.testing,
|
||||
org.eclipse.xtext.xbase.lib;bundle-version="2.14.0"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||
Export-Package: ghidra.xtext.sleigh.tests;x-internal=true
|
@ -0,0 +1,6 @@
|
||||
source.. = src/,\
|
||||
src-gen/,\
|
||||
xtend-gen/
|
||||
bin.includes = .,\
|
||||
META-INF/
|
||||
bin.excludes = **/*.xtend
|
@ -0,0 +1,171 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.tests
|
||||
|
||||
import com.google.inject.Inject
|
||||
import org.eclipse.xtext.diagnostics.Diagnostic
|
||||
import org.eclipse.xtext.testing.InjectWith
|
||||
import org.eclipse.xtext.testing.extensions.InjectionExtension
|
||||
import org.eclipse.xtext.testing.util.ParseHelper
|
||||
import org.eclipse.xtext.testing.validation.ValidationTestHelper
|
||||
import ghidra.xtext.sleigh.sleigh.Model
|
||||
import ghidra.xtext.sleigh.sleigh.SleighPackage
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.^extension.ExtendWith
|
||||
|
||||
@ExtendWith(InjectionExtension)
|
||||
@InjectWith(SleighInjectorProvider)
|
||||
class CrossReferenceTest {
|
||||
|
||||
@Inject extension ParseHelper<Model>
|
||||
@Inject extension ValidationTestHelper
|
||||
|
||||
@Test def void testReferences() {
|
||||
// Macro should have access to registers (globals)
|
||||
var model = '''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V ];
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V ];
|
||||
|
||||
:mov reg,N is op=0 & N & reg {
|
||||
<label1>
|
||||
tmp:1 = N;
|
||||
if (tmp == 0) goto <label1>;
|
||||
reg = tmp;
|
||||
}
|
||||
|
||||
:mov reg,N is op=0 & N & reg {
|
||||
tmp = N; # tmp should not resolve
|
||||
}
|
||||
'''.parse
|
||||
// model.assertNoErrors
|
||||
// temp should not resolve
|
||||
model.assertError(
|
||||
SleighPackage::eINSTANCE.getassignSym(),
|
||||
Diagnostic.LINKING_DIAGNOSTIC,
|
||||
353,
|
||||
3,
|
||||
"tmp"
|
||||
)
|
||||
}
|
||||
|
||||
@Test def void testCrossbuildReferences() {
|
||||
// Macro should have access to registers (globals)
|
||||
var model = '''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V pc ];
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V ];
|
||||
|
||||
CrossbuildAddr0: loc is epsilon [ loc = inst_start; ] { export *:4 loc; }
|
||||
|
||||
Parallel32: "" is op=0x0 & CrossbuildAddr0 {
|
||||
crossbuild CrossbuildAddr0,COMMIT;
|
||||
crossbuild CrossbuildAddr0,LOOP;
|
||||
}
|
||||
|
||||
:^instruction is cc=0x1 & instruction {
|
||||
build instruction;
|
||||
<<LOOP>>
|
||||
pc = 0;
|
||||
goto [pc];
|
||||
}
|
||||
|
||||
:L is op=0x999 {
|
||||
build Parallel32;
|
||||
<<COMMIT>>
|
||||
pc = 0;
|
||||
}
|
||||
'''.parse
|
||||
model.assertNoErrors
|
||||
}
|
||||
|
||||
|
||||
@Test def void testSubPieceReferences() {
|
||||
var model = '''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V ];
|
||||
define register offset=0 size=4 [ BR ];
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V ];
|
||||
|
||||
macro macro_a(arg1,arg2) {
|
||||
local foo = 1;
|
||||
foo = (~foo & foo | foo) << foo;
|
||||
Z = 1;
|
||||
arg1 = 3;
|
||||
arg2 = foo;
|
||||
}
|
||||
|
||||
:mov reg,N,op is op=0 & N & reg & op & op=1 {
|
||||
tmp:1 = 1;
|
||||
tmp2:1 = reg(4);
|
||||
macro_a(reg,tmp);
|
||||
tmp2:2 = BR:2;
|
||||
tmp2:2 = BR(2);
|
||||
tmp2:2 = reg:2;
|
||||
}
|
||||
'''.parse
|
||||
model.assertNoErrors
|
||||
}
|
||||
|
||||
@Test def void testglobalsetReferences() {
|
||||
var model = '''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V contextreg ];
|
||||
define register offset=0 size=4 [ BR ];
|
||||
|
||||
define context contextreg
|
||||
TMode = (0,0)
|
||||
;
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V ];
|
||||
|
||||
GS: reloff is op=100
|
||||
[ reloff = inst_start + 8; TMode=1; globalset(reloff,TMode); globalset(inst_next,TMode); ]
|
||||
{
|
||||
export *:4 reloff;
|
||||
}
|
||||
|
||||
'''.parse
|
||||
model.assertNoErrors
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.tests
|
||||
|
||||
import com.google.inject.Inject
|
||||
import org.eclipse.xtext.diagnostics.Diagnostic
|
||||
import org.eclipse.xtext.testing.InjectWith
|
||||
import org.eclipse.xtext.testing.extensions.InjectionExtension
|
||||
import org.eclipse.xtext.testing.util.ParseHelper
|
||||
import org.eclipse.xtext.testing.validation.ValidationTestHelper
|
||||
import ghidra.xtext.sleigh.sleigh.Model
|
||||
import ghidra.xtext.sleigh.sleigh.SleighPackage
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.^extension.ExtendWith
|
||||
|
||||
@ExtendWith(InjectionExtension)
|
||||
@InjectWith(SleighInjectorProvider)
|
||||
class SleighMacroTest {
|
||||
|
||||
@Inject extension ParseHelper<Model>
|
||||
@Inject extension ValidationTestHelper
|
||||
|
||||
@Test def void testMacros() {
|
||||
var model = '''
|
||||
macro xyz(tom,dick,harry) {
|
||||
tom = dick;
|
||||
harry = tom;
|
||||
tom = 1;
|
||||
}
|
||||
|
||||
macro ijk(do,wop) {
|
||||
do = 1;
|
||||
wop = 1;
|
||||
}
|
||||
'''.parse
|
||||
model.assertNoErrors
|
||||
}
|
||||
|
||||
@Test def void testMacroReferences() {
|
||||
// Macro should have access to registers (globals)
|
||||
var model = '''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z ];
|
||||
|
||||
macro a() {
|
||||
Z = 1;
|
||||
}
|
||||
'''.parse
|
||||
model.assertNoErrors
|
||||
}
|
||||
|
||||
@Test def void testCrossedMacroRefs() {
|
||||
// Macro should not have cross parameter reference
|
||||
var model = '''
|
||||
macro xyz(tom,dick,harry) {
|
||||
tom = dick;
|
||||
harry = do;
|
||||
}
|
||||
|
||||
macro ijk(do,wop) {
|
||||
do = 1;
|
||||
tom = wop;
|
||||
}
|
||||
'''.parse
|
||||
model.assertError(
|
||||
SleighPackage::eINSTANCE.getassignSym(),
|
||||
Diagnostic.LINKING_DIAGNOSTIC,
|
||||
"Couldn't resolve reference to lhsvarnode 'tom'."
|
||||
)
|
||||
model.assertError(
|
||||
SleighPackage::eINSTANCE.getexprSym(),
|
||||
Diagnostic.LINKING_DIAGNOSTIC,
|
||||
"Couldn't resolve reference to EObject 'do'."
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.tests
|
||||
|
||||
import com.google.inject.Inject
|
||||
import org.eclipse.xtext.testing.InjectWith
|
||||
import org.eclipse.xtext.testing.extensions.InjectionExtension
|
||||
import org.eclipse.xtext.testing.util.ParseHelper
|
||||
import org.eclipse.xtext.testing.validation.ValidationTestHelper
|
||||
import ghidra.xtext.sleigh.sleigh.Model
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.^extension.ExtendWith
|
||||
|
||||
@ExtendWith(InjectionExtension)
|
||||
@InjectWith(SleighInjectorProvider)
|
||||
class SleighParsingTest {
|
||||
|
||||
@Inject
|
||||
ParseHelper<Model> parseHelper
|
||||
|
||||
@Inject extension ValidationTestHelper
|
||||
|
||||
@Test def void testEndian() {
|
||||
var model = parseHelper.parse('''
|
||||
define endian= big;
|
||||
''')
|
||||
model.assertNoErrors
|
||||
|
||||
model = parseHelper.parse('''
|
||||
define endian= little;
|
||||
''')
|
||||
model.assertNoErrors
|
||||
|
||||
|
||||
model = parseHelper.parse('''
|
||||
define endian= little;
|
||||
''')
|
||||
|
||||
}
|
||||
|
||||
@Test def void macroUse() {
|
||||
var model = parseHelper.parse('''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V
|
||||
@if ENDIAN == "little"
|
||||
EF
|
||||
@else
|
||||
BF
|
||||
@endif
|
||||
];
|
||||
|
||||
define register offset=100 size=1 [ contReg
|
||||
@if defined(ENDIAN)
|
||||
ifReg
|
||||
@endif
|
||||
];
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
@if ENDIAN == "big"
|
||||
reg = (0,1)
|
||||
@endif
|
||||
cc = (2,3)
|
||||
@else
|
||||
;
|
||||
|
||||
define context contReg
|
||||
contFlag = (0,0)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V
|
||||
@if ENDIAN == "little"
|
||||
EF
|
||||
@else
|
||||
BF
|
||||
@endif
|
||||
];
|
||||
|
||||
macro a(arg1,arg2) {
|
||||
local foo = 1;
|
||||
@if defined(ENDIAN)
|
||||
foo = (~foo & foo | foo) << foo;
|
||||
@endif
|
||||
Z = 1;
|
||||
arg1 = 3;
|
||||
arg2 = foo;
|
||||
}
|
||||
|
||||
CC: "ne" is cc=0x1 { local tmp = !Z; C = 1; tmp = C; export tmp; }
|
||||
CC: "lt" is cc=0x2 { local tmp = N != V; export tmp; }
|
||||
CC: "lt" is cc=0x2 { local tmp:1 = N != V; export tmp; }
|
||||
CC: "lt" is cc=0x2 { tmp:1 = N != V; export tmp; }
|
||||
CC: "lt" is cc=0x2 { tmp:1 = N != V; export tmp; tmp = 1; }
|
||||
|
||||
:mov reg,N,op is op=0 & CC & N & reg & op & op=1
|
||||
{ tmp:1 = CC;
|
||||
@if defined(ENDIAN)
|
||||
reg = tmp;
|
||||
@endif
|
||||
}
|
||||
|
||||
Dest: loc is op=0 [ loc = inst_next; ] { export loc; }
|
||||
:jmp Dest is Dest { call Dest; }
|
||||
|
||||
:set reg is contFlag=0 & op=0 [ contFlag = 1; ] {}
|
||||
''')
|
||||
model.assertNoErrors
|
||||
}
|
||||
|
||||
@Test def void testWith() {
|
||||
var model = parseHelper.parse('''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V
|
||||
@if ENDIAN == "little"
|
||||
EF
|
||||
@else
|
||||
BF
|
||||
@endif
|
||||
];
|
||||
|
||||
define register offset=100 size=1 [ contReg
|
||||
@if defined(ENDIAN)
|
||||
ifReg
|
||||
@endif
|
||||
];
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
@if ENDIAN == "big"
|
||||
reg = (0,1)
|
||||
@endif
|
||||
cc = (2,3)
|
||||
@else
|
||||
;
|
||||
|
||||
define context contReg
|
||||
contFlag = (0,0)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V
|
||||
@if ENDIAN == "little"
|
||||
EF
|
||||
@else
|
||||
BF
|
||||
@endif
|
||||
];
|
||||
|
||||
macro a(arg1,arg2) {
|
||||
local foo = 1;
|
||||
@if defined(ENDIAN)
|
||||
foo = (~foo & foo | foo) << foo;
|
||||
@endif
|
||||
Z = 1;
|
||||
arg1 = 3;
|
||||
arg2 = foo;
|
||||
}
|
||||
|
||||
with CC : cc=0x1 {
|
||||
CC: "ne" is cc=0x1 { local tmp = !Z; C = 1; tmp = C; export tmp; }
|
||||
CC: "lt" is cc=0x2 { local tmp = N != V; export tmp; }
|
||||
CC: "lt" is cc=0x2 { local tmp:1 = N != V; export tmp; }
|
||||
CC: "lt" is cc=0x2 { tmp:1 = N != V; export tmp; }
|
||||
CC: "lt" is cc=0x2 { tmp:1 = N != V; export tmp; tmp = 1; }
|
||||
}
|
||||
|
||||
:mov reg,N,op is op=0 & CC & N & reg & op & op=1
|
||||
{ tmp:1 = CC;
|
||||
@if defined(ENDIAN)
|
||||
reg = tmp;
|
||||
@endif
|
||||
}
|
||||
|
||||
Dest: loc is op=0 [ loc = inst_next; ] { export loc; }
|
||||
:jmp Dest is Dest { call Dest; }
|
||||
|
||||
:set reg is contFlag=0 & op=0 [ contFlag = 1; ] {}
|
||||
''')
|
||||
model.assertNoErrors
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,301 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.tests
|
||||
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.Provider
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil
|
||||
import org.eclipse.xtext.diagnostics.Diagnostic
|
||||
import org.eclipse.xtext.resource.XtextResourceSet
|
||||
import org.eclipse.xtext.testing.InjectWith
|
||||
import org.eclipse.xtext.testing.extensions.InjectionExtension
|
||||
import org.eclipse.xtext.testing.util.ParseHelper
|
||||
import org.eclipse.xtext.testing.validation.ValidationTestHelper
|
||||
import ghidra.xtext.sleigh.sleigh.Model
|
||||
import ghidra.xtext.sleigh.sleigh.SleighPackage
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.^extension.ExtendWith
|
||||
|
||||
@ExtendWith(InjectionExtension)
|
||||
@InjectWith(SleighInjectorProvider)
|
||||
class SleighScopeTest {
|
||||
|
||||
@Inject extension ParseHelper<Model> parser
|
||||
@Inject extension ValidationTestHelper validationTester
|
||||
|
||||
@Inject
|
||||
private Provider<XtextResourceSet> resourceSetProvider;
|
||||
|
||||
// Sample to use for testing
|
||||
// var model = '''
|
||||
// define space register size=2 type=register_space wordsize=1 default;
|
||||
// define register offset=0 size=1 [ Z C N V ];
|
||||
//
|
||||
// define token instr(16)
|
||||
// op = (0,15)
|
||||
// reg = (0,1)
|
||||
// cc = (2,3)
|
||||
// ;
|
||||
//
|
||||
// attach variables [ reg ] [ Z C N V ];
|
||||
//
|
||||
// macro a() {
|
||||
// Z = 1;
|
||||
// }
|
||||
//
|
||||
// CC: "ne" is cc=0x1 { local tmp = !Z; C = 1; tmp = C; export tmp; }
|
||||
// CC: "lt" is cc=0x2 { local tmp = N != V; export tmp; }
|
||||
// CC: "lt" is cc=0x2 { local tmp:1 = N != V; export tmp; }
|
||||
// CC: "lt" is cc=0x2 { tmp:1 = N != V; export tmp; }
|
||||
// CC: "lt" is cc=0x2 { tmp:1 = N != V; export tmp; tmp = 1; }
|
||||
//
|
||||
// :mov reg,N is op=0 & CC & N & reg { tmp:1 = CC; reg = tmp; }
|
||||
// '''.parse
|
||||
|
||||
@Test def void testReferences() {
|
||||
// tmp should not resolve
|
||||
var model = '''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V ];
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V ];
|
||||
|
||||
:mov reg,N is op=0 & C & N & reg { tmp:1 = 1; }
|
||||
|
||||
:mov reg,N is op=0 & C & N & reg { tmp = C; }
|
||||
'''.parse
|
||||
|
||||
assertError(model,
|
||||
SleighPackage::eINSTANCE.getassignSym(),
|
||||
Diagnostic.LINKING_DIAGNOSTIC, 311, 3,
|
||||
"Couldn't resolve reference to lhsvarnode 'tmp'."
|
||||
)
|
||||
|
||||
// tmp should not resolve
|
||||
model = '''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V ];
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V ];
|
||||
|
||||
:mov reg,N is op=0 & C & N & reg { tmp:1 = 1; }
|
||||
|
||||
:mov reg,N is op=0 & C & N & reg { reg = tmp; }
|
||||
'''.parse
|
||||
|
||||
assertError(model,
|
||||
SleighPackage::eINSTANCE.getexprSym(),
|
||||
Diagnostic.LINKING_DIAGNOSTIC, 314, 3,
|
||||
"Couldn't resolve reference to EObject 'tmp'."
|
||||
)
|
||||
}
|
||||
|
||||
@Test def void testMacroReferences() {
|
||||
var model = '''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V ];
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V ];
|
||||
|
||||
macro macro_a(arg1,arg2) {
|
||||
local foo = 1;
|
||||
foo = (~foo & foo | foo) << foo;
|
||||
Z = 1;
|
||||
arg1 = 3;
|
||||
arg2 = foo;
|
||||
}
|
||||
|
||||
:mov reg,N,op is op=0 & N & reg & op & op=1 {
|
||||
tmp:1 = 1;
|
||||
tmp2:1 = reg(4);
|
||||
macro_a(reg,tmp);
|
||||
}
|
||||
'''.parse
|
||||
model.assertNoErrors
|
||||
}
|
||||
|
||||
|
||||
@Test def void testBadAliasReferences() {
|
||||
var model = '''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
:mov AliasRef is op=0 & AliasRef [ AliasRef = inst_next; ] { tmp:1 = AliasRef; } #AliasRef in constraint
|
||||
'''.parse
|
||||
|
||||
assertError(model,
|
||||
SleighPackage::eINSTANCE.getconstraint(),
|
||||
Diagnostic.LINKING_DIAGNOSTIC, 164,8,
|
||||
"Couldn't resolve reference to EObject 'AliasRef'."
|
||||
)
|
||||
|
||||
model = '''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
AliasRef: "empty" is op=0 {}
|
||||
|
||||
:mov AliasRef is op=0 [ AliasRef = inst_next; ] { tmp:1 = AliasRef; } #AliasRef in constraint
|
||||
'''.parse
|
||||
|
||||
var references = EcoreUtil.UsageCrossReferencer.find(model.elements)
|
||||
|
||||
references.forEach[p1, p2 |
|
||||
System.out.println(p1 + " -> " + p2)
|
||||
]
|
||||
}
|
||||
|
||||
@Test def void testAliasRefOverrid() {
|
||||
|
||||
var XtextResourceSet resourceSet = resourceSetProvider.get();
|
||||
|
||||
parser.parse("REGGsrc: reg is reg { export reg; } ", resourceSet)
|
||||
|
||||
var model = parser.parse('''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V ];
|
||||
define register offset=100 size=1 [ contReg ];
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
define context contReg
|
||||
contFlag = (0,0)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V ];
|
||||
|
||||
macro a(arg1,arg2) {
|
||||
local foo = 1;
|
||||
foo = (~foo & foo | foo) << foo;
|
||||
Z = 1;
|
||||
arg1 = 3;
|
||||
arg2 = foo;
|
||||
}
|
||||
|
||||
CC: "ne" is cc=0x1 { local tmp = !Z; C = 1; tmp = C; export tmp; }
|
||||
CC: "lt" is cc=0x2 { local tmp = N != V; export tmp; }
|
||||
CC: "lt" is cc=0x2 { local tmp:1 = N != V; export tmp; }
|
||||
CC: "lt" is cc=0x2 { tmp:1 = N != V; export tmp; }
|
||||
CC: "lt" is cc=0x2 { tmp:1 = N != V; export tmp; tmp = 1; }
|
||||
|
||||
:mov reg,N,op is op=0 & CC & N & reg & op & op=1 { tmp:1 = CC; reg = tmp; }
|
||||
|
||||
:mov REGGsrc,N,op is op=0 & CC & N & reg & REGGsrc & op & op=1 { REGGsrc = op; }
|
||||
|
||||
Dest: loc is op=0 [ loc = inst_next; ] { export loc; }
|
||||
:jmp Dest is Dest { call Dest; }
|
||||
|
||||
:set reg is contFlag=0 & op=0 [ contFlag = 1; ] {}
|
||||
''', resourceSet)
|
||||
model.assertNoErrors;
|
||||
|
||||
var references = EcoreUtil.UsageCrossReferencer.find(model.elements)
|
||||
|
||||
references.forEach[p1, p2 |
|
||||
System.out.println(p1 + " -> " + p2)
|
||||
]
|
||||
|
||||
|
||||
//
|
||||
// model.eAllContents.filter[elem |
|
||||
// elem instanceof SUBTABLESYM
|
||||
// ].forEach[
|
||||
// elem | var list = elem.eCrossReferences; System.out.println(list)
|
||||
// ]
|
||||
//
|
||||
// // now need to verify xref of reg,N,op are not aliases in the match or pcode
|
||||
// var refs = model.eCrossReferences;
|
||||
// refs.forEach[
|
||||
// element | println(element);
|
||||
// ]
|
||||
//
|
||||
// need to verify that an alias in the context var stays as an alias var
|
||||
// unless it is also a global symbol
|
||||
}
|
||||
|
||||
@Test def void testContextAliasRef() {
|
||||
|
||||
var XtextResourceSet resourceSet = resourceSetProvider.get();
|
||||
|
||||
parser.parse("REGGsrc: reg is reg { export reg; } ", resourceSet)
|
||||
|
||||
var model = parser.parse('''
|
||||
define space register size=2 type=register_space wordsize=1 default;
|
||||
define register offset=0 size=1 [ Z C N V ];
|
||||
define register offset=100 size=1 [ contReg ];
|
||||
|
||||
define token instr(16)
|
||||
op = (0,15)
|
||||
reg = (0,1)
|
||||
cc = (2,3)
|
||||
;
|
||||
|
||||
define context contReg
|
||||
contFlag = (0,0)
|
||||
cont2 = (1,1)
|
||||
;
|
||||
|
||||
attach variables [ reg ] [ Z C N V ];
|
||||
|
||||
|
||||
#:mov reg,N,op,vis is op=0 & N & reg & op & op=1 [ vis = op << 20; ] { tmp:1 = vis reg = tmp; }
|
||||
|
||||
#:mov reg,N,op,vis is op=0 & N & reg & op & op=1 [ vis = op << 20; contFlag=op; cont2=contFlag; ] { tmp:1 = vis; reg = tmp; }
|
||||
|
||||
:mov reg,vis is op=0 & reg [ vis = 20; contFlag=vis; ] { tmp:1 = vis; reg = tmp; }
|
||||
|
||||
''', resourceSet)
|
||||
model.assertNoErrors;
|
||||
|
||||
var references = EcoreUtil.UsageCrossReferencer.find(model.elements)
|
||||
|
||||
references.forEach[p1, p2 |
|
||||
System.out.println(p1 + " -> " + p2)
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
Manifest-Version: 1.0
|
||||
Automatic-Module-Name: ghidra.xtext.sleigh.ui.tests
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: ghidra.xtext.sleigh.ui.tests
|
||||
Bundle-Vendor: My Company
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-SymbolicName: ghidra.xtext.sleigh.ui.tests; singleton:=true
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: ghidra.xtext.sleigh.ui,
|
||||
org.junit.jupiter.api;bundle-version="[5.0.0,6.0.0)",
|
||||
org.eclipse.xtext.testing,
|
||||
org.eclipse.xtext.xbase.testing,
|
||||
org.eclipse.xtext.junit4,
|
||||
org.eclipse.xtext.xbase.junit,
|
||||
org.eclipse.core.runtime,
|
||||
org.eclipse.ui.workbench;resolution:=optional
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||
Export-Package: ghidra.xtext.sleigh.ui.tests;x-internal=true
|
@ -0,0 +1,6 @@
|
||||
source.. = src/,\
|
||||
src-gen/,\
|
||||
xtend-gen/
|
||||
bin.includes = .,\
|
||||
META-INF/
|
||||
bin.excludes = **/*.xtend
|
@ -0,0 +1,26 @@
|
||||
Manifest-Version: 1.0
|
||||
Automatic-Module-Name: ghidra.xtext.sleigh.ui
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: ghidra.xtext.sleigh.ui
|
||||
Bundle-Vendor: My Company
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-SymbolicName: ghidra.xtext.sleigh.ui; singleton:=true
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: ghidra.xtext.sleigh,
|
||||
ghidra.xtext.sleigh.ide,
|
||||
org.eclipse.xtext.ui,
|
||||
org.eclipse.xtext.ui.shared,
|
||||
org.eclipse.xtext.ui.codetemplates.ui,
|
||||
org.eclipse.ui.editors;bundle-version="3.5.0",
|
||||
org.eclipse.ui.ide;bundle-version="3.5.0",
|
||||
org.eclipse.ui,
|
||||
org.eclipse.compare,
|
||||
org.eclipse.xtext.builder,
|
||||
org.eclipse.xtext.xbase.lib;bundle-version="2.14.0",
|
||||
org.eclipse.xtend.lib;bundle-version="2.14.0";resolution:=optional
|
||||
Import-Package: org.apache.log4j
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||
Export-Package: ghidra.xtext.sleigh.ui.internal,
|
||||
ghidra.xtext.sleigh.ui.contentassist,
|
||||
ghidra.xtext.sleigh.ui.quickfix
|
||||
Bundle-Activator: ghidra.xtext.sleigh.ui.internal.SleighActivator
|
@ -0,0 +1,7 @@
|
||||
source.. = src/,\
|
||||
src-gen/,\
|
||||
xtend-gen/
|
||||
bin.includes = .,\
|
||||
META-INF/,\
|
||||
plugin.xml
|
||||
bin.excludes = **/*.xtend
|
@ -0,0 +1,513 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.0"?>
|
||||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.ui.editors">
|
||||
<editor
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.XtextEditor"
|
||||
contributorClass="org.eclipse.ui.editors.text.TextEditorActionContributor"
|
||||
default="true"
|
||||
extensions="slaspec,sinc"
|
||||
id="ghidra.xtext.sleigh.Sleigh"
|
||||
name="Sleigh Editor">
|
||||
</editor>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.hyperlinking.OpenDeclarationHandler"
|
||||
commandId="org.eclipse.xtext.ui.editor.hyperlinking.OpenDeclaration">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
<handler
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.handler.ValidateActionHandler"
|
||||
commandId="ghidra.xtext.sleigh.Sleigh.validate">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
<!-- copy qualified name -->
|
||||
<handler
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.copyqualifiedname.EditorCopyQualifiedNameHandler"
|
||||
commandId="org.eclipse.xtext.ui.editor.copyqualifiedname.EditorCopyQualifiedName">
|
||||
<activeWhen>
|
||||
<reference definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened" />
|
||||
</activeWhen>
|
||||
</handler>
|
||||
<handler
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.copyqualifiedname.OutlineCopyQualifiedNameHandler"
|
||||
commandId="org.eclipse.xtext.ui.editor.copyqualifiedname.OutlineCopyQualifiedName">
|
||||
<activeWhen>
|
||||
<and>
|
||||
<reference definitionId="ghidra.xtext.sleigh.Sleigh.XtextEditor.opened" />
|
||||
<iterate>
|
||||
<adapt type="org.eclipse.xtext.ui.editor.outline.IOutlineNode" />
|
||||
</iterate>
|
||||
</and>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
</extension>
|
||||
<extension point="org.eclipse.core.expressions.definitions">
|
||||
<definition id="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
<and>
|
||||
<reference definitionId="isActiveEditorAnInstanceOfXtextEditor"/>
|
||||
<with variable="activeEditor">
|
||||
<test property="org.eclipse.xtext.ui.editor.XtextEditor.languageName"
|
||||
value="ghidra.xtext.sleigh.Sleigh"
|
||||
forcePluginActivation="true"/>
|
||||
</with>
|
||||
</and>
|
||||
</definition>
|
||||
<definition id="ghidra.xtext.sleigh.Sleigh.XtextEditor.opened">
|
||||
<and>
|
||||
<reference definitionId="isXtextEditorActive"/>
|
||||
<with variable="activeEditor">
|
||||
<test property="org.eclipse.xtext.ui.editor.XtextEditor.languageName"
|
||||
value="ghidra.xtext.sleigh.Sleigh"
|
||||
forcePluginActivation="true"/>
|
||||
</with>
|
||||
</and>
|
||||
</definition>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.preferencePages">
|
||||
<page
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.preferences.LanguageRootPreferencePage"
|
||||
id="ghidra.xtext.sleigh.Sleigh"
|
||||
name="Sleigh">
|
||||
<keywordReference id="ghidra.xtext.sleigh.ui.keyword_Sleigh"/>
|
||||
</page>
|
||||
<page
|
||||
category="ghidra.xtext.sleigh.Sleigh"
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.syntaxcoloring.SyntaxColoringPreferencePage"
|
||||
id="ghidra.xtext.sleigh.Sleigh.coloring"
|
||||
name="Syntax Coloring">
|
||||
<keywordReference id="ghidra.xtext.sleigh.ui.keyword_Sleigh"/>
|
||||
</page>
|
||||
<page
|
||||
category="ghidra.xtext.sleigh.Sleigh"
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.templates.XtextTemplatePreferencePage"
|
||||
id="ghidra.xtext.sleigh.Sleigh.templates"
|
||||
name="Templates">
|
||||
<keywordReference id="ghidra.xtext.sleigh.ui.keyword_Sleigh"/>
|
||||
</page>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.propertyPages">
|
||||
<page
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.preferences.LanguageRootPreferencePage"
|
||||
id="ghidra.xtext.sleigh.Sleigh"
|
||||
name="Sleigh">
|
||||
<keywordReference id="ghidra.xtext.sleigh.ui.keyword_Sleigh"/>
|
||||
<enabledWhen>
|
||||
<adapt type="org.eclipse.core.resources.IProject"/>
|
||||
</enabledWhen>
|
||||
<filter name="projectNature" value="org.eclipse.xtext.ui.shared.xtextNature"/>
|
||||
</page>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.keywords">
|
||||
<keyword
|
||||
id="ghidra.xtext.sleigh.ui.keyword_Sleigh"
|
||||
label="Sleigh"/>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.commands">
|
||||
<command
|
||||
description="Trigger expensive validation"
|
||||
id="ghidra.xtext.sleigh.Sleigh.validate"
|
||||
name="Validate">
|
||||
</command>
|
||||
<!-- copy qualified name -->
|
||||
<command
|
||||
id="org.eclipse.xtext.ui.editor.copyqualifiedname.EditorCopyQualifiedName"
|
||||
categoryId="org.eclipse.ui.category.edit"
|
||||
description="Copy the qualified name for the selected element"
|
||||
name="Copy Qualified Name">
|
||||
</command>
|
||||
<command
|
||||
id="org.eclipse.xtext.ui.editor.copyqualifiedname.OutlineCopyQualifiedName"
|
||||
categoryId="org.eclipse.ui.category.edit"
|
||||
description="Copy the qualified name for the selected element"
|
||||
name="Copy Qualified Name">
|
||||
</command>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="popup:#TextEditorContext?after=group.edit">
|
||||
<command
|
||||
commandId="ghidra.xtext.sleigh.Sleigh.validate"
|
||||
style="push"
|
||||
tooltip="Trigger expensive validation">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference
|
||||
definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
</reference>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
<!-- copy qualified name -->
|
||||
<menuContribution locationURI="popup:#TextEditorContext?after=copy">
|
||||
<command commandId="org.eclipse.xtext.ui.editor.copyqualifiedname.EditorCopyQualifiedName"
|
||||
style="push" tooltip="Copy Qualified Name">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened" />
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
<menuContribution locationURI="menu:edit?after=copy">
|
||||
<command commandId="org.eclipse.xtext.ui.editor.copyqualifiedname.EditorCopyQualifiedName"
|
||||
style="push" tooltip="Copy Qualified Name">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened" />
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
<menuContribution locationURI="popup:org.eclipse.xtext.ui.outline?after=additions">
|
||||
<command commandId="org.eclipse.xtext.ui.editor.copyqualifiedname.OutlineCopyQualifiedName"
|
||||
style="push" tooltip="Copy Qualified Name">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<and>
|
||||
<reference definitionId="ghidra.xtext.sleigh.Sleigh.XtextEditor.opened" />
|
||||
<iterate>
|
||||
<adapt type="org.eclipse.xtext.ui.editor.outline.IOutlineNode" />
|
||||
</iterate>
|
||||
</and>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.menus">
|
||||
<menuContribution locationURI="popup:#TextEditorContext?endof=group.find">
|
||||
<command commandId="org.eclipse.xtext.ui.editor.FindReferences">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
</reference>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.findrefs.FindReferencesHandler"
|
||||
commandId="org.eclipse.xtext.ui.editor.FindReferences">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
</extension>
|
||||
<extension point="org.eclipse.core.contenttype.contentTypes">
|
||||
<content-type
|
||||
base-type="org.eclipse.core.runtime.text"
|
||||
file-extensions="slaspec,sinc"
|
||||
id="ghidra.xtext.sleigh.Sleigh.contenttype"
|
||||
name="Sleigh File"
|
||||
priority="normal">
|
||||
</content-type>
|
||||
</extension>
|
||||
<!-- adding resource factories -->
|
||||
<extension
|
||||
point="org.eclipse.emf.ecore.extension_parser">
|
||||
<parser
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.resource.IResourceFactory"
|
||||
type="slaspec">
|
||||
</parser>
|
||||
</extension>
|
||||
<extension point="org.eclipse.xtext.extension_resourceServiceProvider">
|
||||
<resourceServiceProvider
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.resource.IResourceUIServiceProvider"
|
||||
uriExtension="slaspec">
|
||||
</resourceServiceProvider>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.emf.ecore.extension_parser">
|
||||
<parser
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.resource.IResourceFactory"
|
||||
type="sinc">
|
||||
</parser>
|
||||
</extension>
|
||||
<extension point="org.eclipse.xtext.extension_resourceServiceProvider">
|
||||
<resourceServiceProvider
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.resource.IResourceUIServiceProvider"
|
||||
uriExtension="sinc">
|
||||
</resourceServiceProvider>
|
||||
</extension>
|
||||
<!-- marker definitions for ghidra.xtext.sleigh.Sleigh -->
|
||||
<extension
|
||||
id="sleigh.check.fast"
|
||||
name="Sleigh Problem"
|
||||
point="org.eclipse.core.resources.markers">
|
||||
<super type="org.eclipse.xtext.ui.check.fast"/>
|
||||
<persistent value="true"/>
|
||||
</extension>
|
||||
<extension
|
||||
id="sleigh.check.normal"
|
||||
name="Sleigh Problem"
|
||||
point="org.eclipse.core.resources.markers">
|
||||
<super type="org.eclipse.xtext.ui.check.normal"/>
|
||||
<persistent value="true"/>
|
||||
</extension>
|
||||
<extension
|
||||
id="sleigh.check.expensive"
|
||||
name="Sleigh Problem"
|
||||
point="org.eclipse.core.resources.markers">
|
||||
<super type="org.eclipse.xtext.ui.check.expensive"/>
|
||||
<persistent value="true"/>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.preferencePages">
|
||||
<page
|
||||
category="ghidra.xtext.sleigh.Sleigh"
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.validation.ValidatorPreferencePage"
|
||||
id="ghidra.xtext.sleigh.Sleigh.validator.preferencePage"
|
||||
name="Errors/Warnings">
|
||||
<keywordReference id="ghidra.xtext.sleigh.ui.keyword_Sleigh"/>
|
||||
</page>
|
||||
</extension>
|
||||
<extension point="org.eclipse.xtext.builder.participant">
|
||||
<participant
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.builder.IXtextBuilderParticipant"
|
||||
fileExtensions="slaspec,sinc"/>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.preferencePages">
|
||||
<page
|
||||
category="ghidra.xtext.sleigh.Sleigh"
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.builder.preferences.BuilderPreferencePage"
|
||||
id="ghidra.xtext.sleigh.Sleigh.compiler.preferencePage"
|
||||
name="Compiler">
|
||||
<keywordReference id="ghidra.xtext.sleigh.ui.keyword_Sleigh"/>
|
||||
</page>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.propertyPages">
|
||||
<page
|
||||
category="ghidra.xtext.sleigh.Sleigh"
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.builder.preferences.BuilderPreferencePage"
|
||||
id="ghidra.xtext.sleigh.Sleigh.compiler.propertyPage"
|
||||
name="Compiler">
|
||||
<keywordReference id="ghidra.xtext.sleigh.ui.keyword_Sleigh"/>
|
||||
<enabledWhen>
|
||||
<adapt type="org.eclipse.core.resources.IProject"/>
|
||||
</enabledWhen>
|
||||
<filter name="projectNature" value="org.eclipse.xtext.ui.shared.xtextNature"/>
|
||||
</page>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.menus">
|
||||
<menuContribution locationURI="popup:#TextEditorContext?after=xtext.ui.openDeclaration">
|
||||
<command
|
||||
commandId="org.eclipse.xtext.ui.OpenGeneratedFileCommand"
|
||||
id="ghidra.xtext.sleigh.Sleigh.OpenGeneratedCode"
|
||||
style="push">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened" />
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.generator.trace.OpenGeneratedFileHandler"
|
||||
commandId="org.eclipse.xtext.ui.OpenGeneratedFileCommand">
|
||||
<activeWhen>
|
||||
<reference definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened" />
|
||||
</activeWhen>
|
||||
</handler>
|
||||
</extension>
|
||||
<!-- Quick Outline -->
|
||||
<extension
|
||||
point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.outline.quickoutline.ShowQuickOutlineActionHandler"
|
||||
commandId="org.eclipse.xtext.ui.editor.outline.QuickOutline">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.commands">
|
||||
<command
|
||||
description="Open the quick outline."
|
||||
id="org.eclipse.xtext.ui.editor.outline.QuickOutline"
|
||||
name="Quick Outline">
|
||||
</command>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="popup:#TextEditorContext?after=group.open">
|
||||
<command commandId="org.eclipse.xtext.ui.editor.outline.QuickOutline"
|
||||
style="push"
|
||||
tooltip="Open Quick Outline">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened"/>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
<!-- quickfix marker resolution generator for ghidra.xtext.sleigh.Sleigh -->
|
||||
<extension
|
||||
point="org.eclipse.ui.ide.markerResolution">
|
||||
<markerResolutionGenerator
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator"
|
||||
markerType="ghidra.xtext.sleigh.ui.sleigh.check.fast">
|
||||
<attribute
|
||||
name="FIXABLE_KEY"
|
||||
value="true">
|
||||
</attribute>
|
||||
</markerResolutionGenerator>
|
||||
<markerResolutionGenerator
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator"
|
||||
markerType="ghidra.xtext.sleigh.ui.sleigh.check.normal">
|
||||
<attribute
|
||||
name="FIXABLE_KEY"
|
||||
value="true">
|
||||
</attribute>
|
||||
</markerResolutionGenerator>
|
||||
<markerResolutionGenerator
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator"
|
||||
markerType="ghidra.xtext.sleigh.ui.sleigh.check.expensive">
|
||||
<attribute
|
||||
name="FIXABLE_KEY"
|
||||
value="true">
|
||||
</attribute>
|
||||
</markerResolutionGenerator>
|
||||
</extension>
|
||||
<!-- Rename Refactoring -->
|
||||
<extension point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.refactoring.ui.DefaultRenameElementHandler"
|
||||
commandId="org.eclipse.xtext.ui.refactoring.RenameElement">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="popup:#TextEditorContext?after=group.edit">
|
||||
<command commandId="org.eclipse.xtext.ui.refactoring.RenameElement"
|
||||
style="push">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference
|
||||
definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
</reference>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.preferencePages">
|
||||
<page
|
||||
category="ghidra.xtext.sleigh.Sleigh"
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.refactoring.ui.RefactoringPreferencePage"
|
||||
id="ghidra.xtext.sleigh.Sleigh.refactoring"
|
||||
name="Refactoring">
|
||||
<keywordReference id="ghidra.xtext.sleigh.ui.keyword_Sleigh"/>
|
||||
</page>
|
||||
</extension>
|
||||
<extension point="org.eclipse.compare.contentViewers">
|
||||
<viewer id="ghidra.xtext.sleigh.Sleigh.compare.contentViewers"
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.compare.InjectableViewerCreator"
|
||||
extensions="slaspec,sinc">
|
||||
</viewer>
|
||||
<contentTypeBinding
|
||||
contentTypeId="ghidra.xtext.sleigh.Sleigh.contenttype"
|
||||
contentViewerId="ghidra.xtext.sleigh.Sleigh.compare.contentViewers" />
|
||||
</extension>
|
||||
<extension point="org.eclipse.compare.contentMergeViewers">
|
||||
<viewer id="ghidra.xtext.sleigh.Sleigh.compare.contentMergeViewers"
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.compare.InjectableViewerCreator"
|
||||
extensions="slaspec,sinc" label="Sleigh Compare">
|
||||
</viewer>
|
||||
<contentTypeBinding
|
||||
contentTypeId="ghidra.xtext.sleigh.Sleigh.contenttype"
|
||||
contentMergeViewerId="ghidra.xtext.sleigh.Sleigh.compare.contentMergeViewers" />
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.editors.documentProviders">
|
||||
<provider id="ghidra.xtext.sleigh.Sleigh.editors.documentProviders"
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.model.XtextDocumentProvider"
|
||||
extensions="slaspec,sinc">
|
||||
</provider>
|
||||
</extension>
|
||||
<extension point="org.eclipse.team.core.fileTypes">
|
||||
<fileTypes
|
||||
extension="slaspec"
|
||||
type="text">
|
||||
</fileTypes>
|
||||
<fileTypes
|
||||
extension="sinc"
|
||||
type="text">
|
||||
</fileTypes>
|
||||
</extension>
|
||||
<!-- quickfix marker resolution generator for ghidra.xtext.sleigh.Sleigh -->
|
||||
<extension
|
||||
point="org.eclipse.ui.ide.markerResolution">
|
||||
<markerResolutionGenerator
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator"
|
||||
markerType="ghidra.xtext.sleigh.ui.sleigh.check.fast">
|
||||
<attribute
|
||||
name="FIXABLE_KEY"
|
||||
value="true">
|
||||
</attribute>
|
||||
</markerResolutionGenerator>
|
||||
<markerResolutionGenerator
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator"
|
||||
markerType="ghidra.xtext.sleigh.ui.sleigh.check.normal">
|
||||
<attribute
|
||||
name="FIXABLE_KEY"
|
||||
value="true">
|
||||
</attribute>
|
||||
</markerResolutionGenerator>
|
||||
<markerResolutionGenerator
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator"
|
||||
markerType="ghidra.xtext.sleigh.ui.sleigh.check.expensive">
|
||||
<attribute
|
||||
name="FIXABLE_KEY"
|
||||
value="true">
|
||||
</attribute>
|
||||
</markerResolutionGenerator>
|
||||
</extension>
|
||||
<!-- Rename Refactoring -->
|
||||
<extension point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.refactoring.ui.DefaultRenameElementHandler"
|
||||
commandId="org.eclipse.xtext.ui.refactoring.RenameElement">
|
||||
<activeWhen>
|
||||
<reference
|
||||
definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
</reference>
|
||||
</activeWhen>
|
||||
</handler>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="popup:#TextEditorContext?after=group.edit">
|
||||
<command commandId="org.eclipse.xtext.ui.refactoring.RenameElement"
|
||||
style="push">
|
||||
<visibleWhen checkEnabled="false">
|
||||
<reference
|
||||
definitionId="ghidra.xtext.sleigh.Sleigh.Editor.opened">
|
||||
</reference>
|
||||
</visibleWhen>
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.preferencePages">
|
||||
<page
|
||||
category="ghidra.xtext.sleigh.Sleigh"
|
||||
class="ghidra.xtext.sleigh.ui.SleighExecutableExtensionFactory:org.eclipse.xtext.ui.refactoring.ui.RefactoringPreferencePage"
|
||||
id="ghidra.xtext.sleigh.Sleigh.refactoring"
|
||||
name="Refactoring">
|
||||
<keywordReference id="ghidra.xtext.sleigh.ui.keyword_Sleigh"/>
|
||||
</page>
|
||||
</extension>
|
||||
</plugin>
|
@ -0,0 +1,43 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ui;
|
||||
|
||||
import org.eclipse.debug.core.model.IProcess;
|
||||
import org.eclipse.debug.ui.console.IConsole;
|
||||
import org.eclipse.debug.ui.console.IConsoleLineTracker;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
|
||||
public class ConsoleLineTracker implements IConsoleLineTracker {
|
||||
|
||||
@Override
|
||||
public void init(IConsole console) {
|
||||
IProcess process = console.getProcess();
|
||||
|
||||
System.out.println(process.getLabel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lineAppended(IRegion line) {
|
||||
System.out.println(line.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,202 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ui
|
||||
|
||||
import ghidra.xtext.sleigh.sleigh.DefineSym
|
||||
import ghidra.xtext.sleigh.sleigh.SUBTABLESYM
|
||||
import ghidra.xtext.sleigh.sleigh.aliasSym
|
||||
import ghidra.xtext.sleigh.sleigh.integerValue
|
||||
import ghidra.xtext.sleigh.sleigh.macroDefine
|
||||
import ghidra.xtext.sleigh.sleigh.printpiece
|
||||
import ghidra.xtext.sleigh.sleigh.subconstructor
|
||||
import java.math.BigInteger
|
||||
import org.eclipse.emf.common.util.EList
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.xtext.conversion.ValueConverterException
|
||||
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
|
||||
import org.eclipse.xtext.ui.editor.hover.html.DefaultEObjectHoverProvider
|
||||
import org.eclipse.xtext.util.Strings
|
||||
|
||||
class SleighEObjectHoverProvider extends DefaultEObjectHoverProvider {
|
||||
|
||||
EObject model
|
||||
|
||||
override boolean hasHover(EObject o) {
|
||||
if (o instanceof integerValue) { return true; }
|
||||
return super.hasHover(o)
|
||||
}
|
||||
|
||||
override String getFirstLine(EObject o) {
|
||||
var label = getLabel(o);
|
||||
var str = o.eClass().getName();
|
||||
if (label == null) {
|
||||
str += "";
|
||||
} else {
|
||||
str = " <b>" + label + "</b>";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
override String getLabel(EObject element) {
|
||||
switch element {
|
||||
DefineSym:
|
||||
return " <b>" + element.name + "</b>"
|
||||
default:
|
||||
return super.getLabel(element)
|
||||
}
|
||||
}
|
||||
|
||||
override String getDocumentation(EObject element) {
|
||||
switch element {
|
||||
DefineSym:
|
||||
return getDefineSymText(element)
|
||||
SUBTABLESYM:
|
||||
return getSubTableText(element)
|
||||
aliasSym:
|
||||
return getSubTableText(element)
|
||||
integerValue:
|
||||
return getIntegerFormats(element)
|
||||
default:
|
||||
return super.getDocumentation(element)
|
||||
}
|
||||
}
|
||||
|
||||
def getIntegerFormats(integerValue value) {
|
||||
var retStr = "";
|
||||
var valueOf = getIntValue(value)
|
||||
|
||||
retStr = retStr + "<p style=\"color:red;line-height:50%;\">" + "0b" + valueOf.toString(2) + "</p>\n"
|
||||
retStr = retStr + "<p style=\"color:red;line-height:50%;\">" + "0x" + valueOf.toString(16) + "</p>\n"
|
||||
retStr = retStr + "<p style=\"color:red;line-height:50%;\">" + " " + valueOf.toString(10) + "</p>\n"
|
||||
|
||||
if (retStr.length == 0) {
|
||||
return value.value;
|
||||
}
|
||||
return retStr;
|
||||
}
|
||||
|
||||
def getIntValue(integerValue value) {
|
||||
var parseString = value.value;
|
||||
var string = value.value
|
||||
if (Strings.isEmpty(parseString))
|
||||
throw new NumberFormatException("Couldn't convert empty string to an int value.");
|
||||
try {
|
||||
var radix = 10;
|
||||
if (parseString.startsWith("0x") || parseString.startsWith("0X")) {
|
||||
parseString = string.substring(2);
|
||||
radix=16;
|
||||
}
|
||||
if (parseString.startsWith("0b") || parseString.startsWith("0B")) {
|
||||
parseString = string.substring(2);
|
||||
radix=2;
|
||||
}
|
||||
return new BigInteger(parseString,radix);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new NumberFormatException("Couldn't convert '" + string + "' to a BigInteger value.");
|
||||
}
|
||||
}
|
||||
|
||||
def getDefineSymText(DefineSym element) {
|
||||
var retStr = "";
|
||||
model = element.eResource.contents.get(0);
|
||||
var macDefs = model.eAllContents.filter(typeof(macroDefine));
|
||||
var len = "";
|
||||
while (macDefs.hasNext) {
|
||||
var next = macDefs.next;
|
||||
if (next.defineType.equals("@define")) {
|
||||
if (next.definename.name == element.name) {
|
||||
retStr = retStr + "<p style=\"color:red;line-height:100%;\">" + next.value + "</p>\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
if (retStr.length == 0) {
|
||||
return element.name;
|
||||
}
|
||||
return retStr;
|
||||
}
|
||||
|
||||
def getSubTableText(SUBTABLESYM element) {
|
||||
var retStr = "";
|
||||
model = element.eResource.contents.get(0);
|
||||
var subs = model.eAllContents.filter(typeof(subconstructor));
|
||||
var len = "";
|
||||
while (subs.hasNext) {
|
||||
var next = subs.next;
|
||||
if (next.tableName.name == element.name) {
|
||||
retStr = retStr + "<p style=\"color:red;line-height:100%;\">" + formatString(next.print.printpieces) +
|
||||
" is " + formatConstraintString(next.match.constraints) + "</p>\n"
|
||||
}
|
||||
}
|
||||
if (retStr.length == 0) {
|
||||
return element.name;
|
||||
}
|
||||
return retStr;
|
||||
}
|
||||
|
||||
def getSubTableText(aliasSym element) {
|
||||
var retStr = "";
|
||||
model = element.eResource.contents.get(0);
|
||||
var subs = model.eAllContents.filter(typeof(subconstructor));
|
||||
while (subs.hasNext) {
|
||||
var next = subs.next;
|
||||
if (next.tableName.name == element.sym) {
|
||||
retStr = retStr + "<p style=\"color:red;line-height:100%;\">" + formatString(next.print.printpieces) +
|
||||
" is " + formatConstraintString(next.match.constraints) + "</p>\n"
|
||||
}
|
||||
}
|
||||
if (retStr.length != 0) {
|
||||
return retStr;
|
||||
}
|
||||
var macDefs = model.eAllContents.filter(typeof(macroDefine));
|
||||
while (macDefs.hasNext) {
|
||||
var next = macDefs.next;
|
||||
if (next.defineType.equals("@define")) {
|
||||
if (next.definename.name == element.sym) {
|
||||
retStr = retStr + "<p style=\"color:red;line-height:100%;\">" + next.value + "</p>\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
if (retStr.length == 0) {
|
||||
return element.sym;
|
||||
}
|
||||
return retStr;
|
||||
}
|
||||
|
||||
def String formatString(EList<printpiece> list) {
|
||||
var str = "<span style=\"color:#0000FF;\">";
|
||||
var iter = list.iterator;
|
||||
while (iter.hasNext) {
|
||||
var piece = iter.next;
|
||||
if (piece.str == null) {
|
||||
if (piece.sym != null) {
|
||||
str += piece.sym.sym;
|
||||
} else {
|
||||
str = '{empty}'
|
||||
}
|
||||
} else {
|
||||
str += piece.str;
|
||||
}
|
||||
}
|
||||
str += "</span>"
|
||||
str
|
||||
}
|
||||
|
||||
def String formatConstraintString(EObject o) {
|
||||
var node = NodeModelUtils.getNode(o);
|
||||
return node.text
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,238 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ui;
|
||||
|
||||
import static org.eclipse.xtext.ui.editor.syntaxcoloring.DefaultHighlightingConfiguration.COMMENT_ID;
|
||||
import static org.eclipse.xtext.ui.editor.syntaxcoloring.DefaultHighlightingConfiguration.KEYWORD_ID;
|
||||
import static ghidra.xtext.sleigh.ui.SleighHighlightingConfiguration.CONTEXTFIELD;
|
||||
import static ghidra.xtext.sleigh.ui.SleighHighlightingConfiguration.LOCAL;
|
||||
import static ghidra.xtext.sleigh.ui.SleighHighlightingConfiguration.PRINTPIECE;
|
||||
import static ghidra.xtext.sleigh.ui.SleighHighlightingConfiguration.SUBTABLE;
|
||||
import static ghidra.xtext.sleigh.ui.SleighHighlightingConfiguration.TOKENFIELD;
|
||||
import static ghidra.xtext.sleigh.ui.SleighHighlightingConfiguration.VARIABLE;
|
||||
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.CrossReference;
|
||||
import org.eclipse.xtext.impl.TerminalRuleImpl;
|
||||
import org.eclipse.xtext.nodemodel.BidiIterator;
|
||||
import org.eclipse.xtext.nodemodel.BidiTreeIterator;
|
||||
import org.eclipse.xtext.nodemodel.INode;
|
||||
import org.eclipse.xtext.nodemodel.impl.HiddenLeafNode;
|
||||
import org.eclipse.xtext.nodemodel.impl.LeafNode;
|
||||
import org.eclipse.xtext.resource.XtextResource;
|
||||
import org.eclipse.xtext.util.CancelIndicator;
|
||||
import org.eclipse.xtext.ide.editor.syntaxcoloring.DefaultSemanticHighlightingCalculator;
|
||||
import org.eclipse.xtext.ide.editor.syntaxcoloring.IHighlightedPositionAcceptor;
|
||||
|
||||
import ghidra.xtext.sleigh.sleigh.CONTEXTSYM;
|
||||
import ghidra.xtext.sleigh.sleigh.LOCALSYM;
|
||||
import ghidra.xtext.sleigh.sleigh.SUBTABLESYM;
|
||||
import ghidra.xtext.sleigh.sleigh.TOKENSYM;
|
||||
import ghidra.xtext.sleigh.sleigh.VARSYM;
|
||||
import ghidra.xtext.sleigh.sleigh.aliasSym;
|
||||
import ghidra.xtext.sleigh.sleigh.anysymbol;
|
||||
import ghidra.xtext.sleigh.sleigh.assignSym;
|
||||
import ghidra.xtext.sleigh.sleigh.constraint;
|
||||
import ghidra.xtext.sleigh.sleigh.exprSym;
|
||||
import ghidra.xtext.sleigh.sleigh.fielddef;
|
||||
import ghidra.xtext.sleigh.sleigh.isKeyword;
|
||||
import ghidra.xtext.sleigh.sleigh.pexprSym;
|
||||
import ghidra.xtext.sleigh.sleigh.printpiece;
|
||||
import ghidra.xtext.sleigh.sleigh.valuepart;
|
||||
import ghidra.xtext.sleigh.sleigh.varpart;
|
||||
|
||||
public class SleighHighlightingCalculator extends DefaultSemanticHighlightingCalculator {
|
||||
|
||||
@Override
|
||||
public void provideHighlightingFor(XtextResource resource, IHighlightedPositionAcceptor acceptor,
|
||||
CancelIndicator cancelIndicator) {
|
||||
|
||||
if (resource == null || resource.getParseResult() == null)
|
||||
return;
|
||||
|
||||
super.provideHighlightingFor(resource, acceptor, cancelIndicator);
|
||||
|
||||
INode root = resource.getParseResult().getRootNode();
|
||||
BidiTreeIterator<INode> it = root.getAsTreeIterable().iterator();
|
||||
while (it.hasNext()) {
|
||||
INode node = it.next();
|
||||
EObject grammarElement = node.getGrammarElement();
|
||||
EObject semanticElement = node.getSemanticElement();
|
||||
printNodeInfo(node, grammarElement, semanticElement);
|
||||
|
||||
// if (node instanceof CompositeNodeWithSemanticElement
|
||||
// && semanticElement instanceof contextfielddef) {
|
||||
// setStyles(acceptor, it, CONTEXTFIELD, "GROUP", CONTEXTFIELD);
|
||||
// setStyles(acceptor, node.getAsTreeIterable().reverse()
|
||||
// .iterator(), null, CONTEXTFIELD);
|
||||
// } else
|
||||
if (semanticElement instanceof VARSYM) {
|
||||
setNodeStyle(acceptor, node, VARIABLE);
|
||||
// } else if (grammarElement instanceof Keyword) {
|
||||
// setStyles(acceptor, it, KEYWORD_ID);
|
||||
} else if (semanticElement instanceof CONTEXTSYM) {
|
||||
setNodeStyle(acceptor, node, CONTEXTFIELD);
|
||||
} else if (semanticElement instanceof LOCALSYM) {
|
||||
setNodeStyle(acceptor, node, LOCAL);
|
||||
} else if (semanticElement instanceof TOKENSYM) {
|
||||
setNodeStyle(acceptor, node, TOKENFIELD);
|
||||
} else if (semanticElement instanceof fielddef) {
|
||||
setNodeStyle(acceptor, node, TOKENFIELD);
|
||||
} else if (semanticElement instanceof anysymbol) {
|
||||
setStyle(acceptor, node, semanticElement);
|
||||
} else if (grammarElement instanceof CrossReference) {
|
||||
CrossReference defn = (CrossReference) grammarElement;
|
||||
EObject semElem = semanticElement;
|
||||
if (semElem instanceof varpart || semElem instanceof valuepart) {
|
||||
setNodeStyle(acceptor, node, VARIABLE);
|
||||
} else if (semElem instanceof LOCALSYM) {
|
||||
setNodeStyle(acceptor, node, LOCAL);
|
||||
} else if (semElem instanceof exprSym) {
|
||||
exprSym sym = (exprSym) semElem;
|
||||
EObject vnode = sym.getVnode();
|
||||
if (vnode != null) {
|
||||
setStyle(acceptor, node, vnode);
|
||||
} else {
|
||||
// System.out.println(" exprSym--" + semElem);
|
||||
}
|
||||
} else if (semElem instanceof assignSym) {
|
||||
// TODO: Causing a lazy linking error sometimes
|
||||
// Possibly something wrong with the grammer for [lhsvarnode]
|
||||
// ERROR org.eclipse.xtext.linking.lazy.LazyLinkingResource - An element of type ghidra.xtext.sleigh.sleigh.impl.aliasSymImpl is not assignable to the reference assignSym.symref
|
||||
assignSym sym = (assignSym) semElem;
|
||||
EObject vnode = sym.getSymref();
|
||||
if (vnode != null) {
|
||||
setStyle(acceptor, node, vnode);
|
||||
} else {
|
||||
// System.out.println(" exprSym--" + semElem);
|
||||
}
|
||||
}
|
||||
else if (semElem instanceof constraint) {
|
||||
constraint sym = (constraint) semElem;
|
||||
EObject vnode = sym.getSym();
|
||||
if (vnode != null) {
|
||||
setStyle(acceptor, node, vnode);
|
||||
} else {
|
||||
// System.out.println(" exprSym--" + semElem);
|
||||
}
|
||||
}
|
||||
else if (semElem instanceof pexprSym) {
|
||||
pexprSym sym = (pexprSym) semElem;
|
||||
EObject vnode = sym.getSym();
|
||||
if (vnode != null) {
|
||||
setStyle(acceptor, node, vnode);
|
||||
} else {
|
||||
// System.out.println(" exprSym--" + semElem);
|
||||
}
|
||||
}
|
||||
else if (semElem instanceof aliasSym) {
|
||||
System.out.println(" semElem="+semElem);
|
||||
}
|
||||
else {
|
||||
// System.out.println(" semElem="+semElem);
|
||||
}
|
||||
} else if (semanticElement instanceof isKeyword) {
|
||||
setStyles(acceptor, it, KEYWORD_ID);
|
||||
} else if (semanticElement instanceof aliasSym && semanticElement.eContainer() instanceof printpiece) {
|
||||
setStyles(acceptor, it, PRINTPIECE);
|
||||
} else if (semanticElement instanceof printpiece) {
|
||||
setStyles(acceptor, it, PRINTPIECE);
|
||||
} else if (node instanceof HiddenLeafNode
|
||||
&& grammarElement instanceof TerminalRuleImpl) {
|
||||
processHiddenNode(acceptor, (HiddenLeafNode) node);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void setStyle(IHighlightedPositionAcceptor acceptor, INode n, EObject vnode) {
|
||||
if (vnode instanceof LOCALSYM) {
|
||||
setNodeStyle(acceptor, n, LOCAL);
|
||||
} else if (vnode instanceof VARSYM) {
|
||||
setNodeStyle(acceptor, n, VARIABLE);
|
||||
} else if (vnode instanceof SUBTABLESYM) {
|
||||
setNodeStyle(acceptor, n, SUBTABLE);
|
||||
} else if (vnode instanceof fielddef) {
|
||||
setNodeStyle(acceptor, n, TOKENFIELD);
|
||||
} else {
|
||||
// System.out.println(" symtype = " + vnode);
|
||||
}
|
||||
}
|
||||
|
||||
private void setNodeStyle(IHighlightedPositionAcceptor acceptor, INode n, String styleName) {
|
||||
acceptor.addPosition(n.getOffset(), n.getLength(), styleName);
|
||||
}
|
||||
|
||||
private void printNodeInfo(INode node, EObject grammarElement,
|
||||
EObject semanticElement) {
|
||||
String grammar = "<no-grammar>";
|
||||
String semantic = "<no-semantic>";
|
||||
|
||||
if (grammarElement != null) {
|
||||
grammar = grammarElement.getClass().getSimpleName();
|
||||
}
|
||||
if (semanticElement != null) {
|
||||
semantic = semanticElement.getClass().getSimpleName();
|
||||
}
|
||||
if (grammarElement instanceof TerminalRuleImpl) return;
|
||||
if (! (node instanceof LeafNode)) return;
|
||||
// System.err.println( "Node: " + node.getClass().getSimpleName() +
|
||||
// "\t\t\t\t" + grammar + " =\t\t\t\t" + semantic + "\"" + node.getText() + "\"");
|
||||
}
|
||||
|
||||
void setStyles(IHighlightedPositionAcceptor acceptor,
|
||||
BidiIterator<INode> it, String... styles) {
|
||||
for (String s : styles) {
|
||||
if (!it.hasNext())
|
||||
return;
|
||||
INode n = skipWhiteSpace(acceptor, it);
|
||||
if (n != null && s != null)
|
||||
acceptor.addPosition(n.getOffset(), n.getLength(), s);
|
||||
}
|
||||
}
|
||||
|
||||
INode skipWhiteSpace(IHighlightedPositionAcceptor acceptor,
|
||||
BidiIterator<INode> it) {
|
||||
INode n = null;
|
||||
while (it.hasNext()
|
||||
&& (n = it.next()).getClass() == HiddenLeafNode.class)
|
||||
processHiddenNode(acceptor, (HiddenLeafNode) n);
|
||||
return n;
|
||||
}
|
||||
|
||||
INode skipWhiteSpaceBackwards(IHighlightedPositionAcceptor acceptor,
|
||||
BidiIterator<INode> it) {
|
||||
INode n = null;
|
||||
while (it.hasPrevious()
|
||||
&& (n = it.previous()).getClass() == HiddenLeafNode.class)
|
||||
processHiddenNode(acceptor, (HiddenLeafNode) n);
|
||||
return n;
|
||||
}
|
||||
|
||||
void processHiddenNode(IHighlightedPositionAcceptor acceptor,
|
||||
HiddenLeafNode node) {
|
||||
if (node.getGrammarElement() instanceof TerminalRuleImpl) {
|
||||
TerminalRuleImpl ge = (TerminalRuleImpl) node.getGrammarElement();
|
||||
String name = ge.getName();
|
||||
if (name.equalsIgnoreCase("PDL_COMMENT") || name.equalsIgnoreCase("ML_COMMENT") || name.equalsIgnoreCase("SL_COMMENT")) {
|
||||
acceptor.addPosition(node.getOffset(), node.getLength(), COMMENT_ID);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ui;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.eclipse.xtext.ui.editor.syntaxcoloring.DefaultHighlightingConfiguration;
|
||||
import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingConfigurationAcceptor;
|
||||
import org.eclipse.xtext.ui.editor.utils.TextStyle;
|
||||
|
||||
public class SleighHighlightingConfiguration extends DefaultHighlightingConfiguration {
|
||||
// provide an id string for the highlighting calculator
|
||||
public static final String CONTEXTFIELD = "Context Field";
|
||||
public static final String TOKENFIELD = "Token Field";
|
||||
public static final String SYMBOL = "Symbol";
|
||||
public static final String VARIABLE = "Variable";
|
||||
public static final String ATTACHEDSYM = "Attached Symbol";
|
||||
public static final String PRINTPIECE = "Print Piece";
|
||||
public static final String LOCAL = "Local Symbol";
|
||||
public static final String SUBTABLE = "SubTable";
|
||||
|
||||
public void configure(IHighlightingConfigurationAcceptor acceptor) {
|
||||
super.configure(acceptor);
|
||||
addType(acceptor, CONTEXTFIELD, 50, 50, 0, SWT.ITALIC);
|
||||
addType(acceptor, TOKENFIELD, 50, 50, 0, SWT.NORMAL);
|
||||
addType(acceptor, SYMBOL, 50, 50, 50, TextStyle.DEFAULT_FONT_STYLE);
|
||||
addType(acceptor, VARIABLE, 106, 62, 63, SWT.BOLD);
|
||||
addType(acceptor, ATTACHEDSYM, 50, 50, 50, SWT.BOLD);
|
||||
addType(acceptor, PRINTPIECE, 0,0,255, SWT.BOLD);
|
||||
addType(acceptor, LOCAL, 40,40,40, SWT.ITALIC);
|
||||
addType(acceptor, SUBTABLE, 192, 82, 5, SWT.NORMAL);
|
||||
}
|
||||
|
||||
public void addType(IHighlightingConfigurationAcceptor acceptor, String s,
|
||||
int r, int g, int b, int style) {
|
||||
addType(acceptor, s, new RGB(r,g,b), style);
|
||||
}
|
||||
|
||||
public void addType(IHighlightingConfigurationAcceptor acceptor, String s,
|
||||
RGB rgb, int style) {
|
||||
TextStyle textStyle = new TextStyle();
|
||||
textStyle.setBackgroundColor(new RGB(255, 255, 255));
|
||||
textStyle.setColor(rgb);
|
||||
textStyle.setStyle(style);
|
||||
acceptor.acceptDefaultHighlighting(s, s, textStyle);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package ghidra.xtext.sleigh.ui
|
||||
|
||||
import org.eclipse.xtext.resource.SaveOptions
|
||||
import org.eclipse.xtext.ui.editor.model.edit.DefaultTextEditComposer
|
||||
|
||||
class SleighTextEditComposer extends DefaultTextEditComposer {
|
||||
|
||||
override SaveOptions getSaveOptions() {
|
||||
return SaveOptions.newBuilder().format().getOptions();
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ui
|
||||
|
||||
import com.google.inject.Binder
|
||||
import ghidra.xtext.sleigh.ui.labeling.SleighLabelProvider
|
||||
import org.eclipse.jface.viewers.ILabelProvider
|
||||
import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
|
||||
import org.eclipse.xtext.ide.editor.syntaxcoloring.ISemanticHighlightingCalculator
|
||||
import org.eclipse.xtext.ui.editor.contentassist.ContentProposalLabelProvider
|
||||
import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider
|
||||
import org.eclipse.xtext.ui.editor.model.edit.ITextEditComposer
|
||||
import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingConfiguration
|
||||
|
||||
/**
|
||||
* Use this class to register components to be used within the Eclipse IDE.
|
||||
*/
|
||||
@FinalFieldsConstructor
|
||||
class SleighUiModule extends AbstractSleighUiModule {
|
||||
|
||||
override void configureContentProposalLabelProvider(Binder binder) {
|
||||
binder.bind(ILabelProvider).annotatedWith(ContentProposalLabelProvider).to(SleighLabelProvider);
|
||||
}
|
||||
|
||||
def Class<? extends IHighlightingConfiguration> bindIHighlightingConfiguration() {
|
||||
return SleighHighlightingConfiguration
|
||||
}
|
||||
|
||||
def Class<? extends ISemanticHighlightingCalculator> bindISemanticHighlightingCalculator() {
|
||||
return SleighHighlightingCalculator
|
||||
}
|
||||
|
||||
def Class<? extends IEObjectHoverProvider> bindIEObjectHoverProvider() {
|
||||
return SleighEObjectHoverProvider
|
||||
}
|
||||
|
||||
def Class<? extends ITextEditComposer> bindITextEditComposer() {
|
||||
return SleighTextEditComposer
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ui.contentassist
|
||||
|
||||
|
||||
/**
|
||||
* See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#content-assist
|
||||
* on how to customize the content assistant.
|
||||
*/
|
||||
class SleighProposalProvider extends AbstractSleighProposalProvider {
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ui.labeling
|
||||
|
||||
import com.google.inject.Inject
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet
|
||||
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
|
||||
import org.eclipse.xtext.resource.IEObjectDescription
|
||||
import org.eclipse.xtext.resource.IReferenceDescription
|
||||
import org.eclipse.xtext.ui.label.DefaultDescriptionLabelProvider
|
||||
import ghidra.xtext.sleigh.sleigh.exportStmt
|
||||
import ghidra.xtext.sleigh.sleigh.pequation
|
||||
import ghidra.xtext.sleigh.sleigh.statement
|
||||
|
||||
/**
|
||||
* Provides labels for IEObjectDescriptions and IResourceDescriptions.
|
||||
*
|
||||
* See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides labels for a IEObjectDescriptions and IResourceDescriptions.
|
||||
*
|
||||
* see http://www.eclipse.org/Xtext/documentation.html#labelProvider
|
||||
*/
|
||||
class SleighDescriptionLabelProvider extends DefaultDescriptionLabelProvider {
|
||||
|
||||
@Inject ResourceSet rdp
|
||||
|
||||
// Labels and icons can be computed like this:
|
||||
override String getText(Object element) {
|
||||
var ele = element;
|
||||
|
||||
if (element instanceof IReferenceDescription) {
|
||||
var o = rdp.getEObject(element.sourceEObjectUri,true);
|
||||
if (o != null){
|
||||
return containerLine(o);
|
||||
}
|
||||
return element.EReference.name
|
||||
}
|
||||
return super.getText(ele);
|
||||
}
|
||||
|
||||
def String containerLine(EObject o) {
|
||||
var c = o;
|
||||
var text = NodeModelUtils.getNode(o).text
|
||||
while (c.eContainer != null) {
|
||||
if (c instanceof pequation) {
|
||||
return NodeModelUtils.getNode(c).text
|
||||
}
|
||||
if (c instanceof statement ||
|
||||
c instanceof exportStmt
|
||||
) {
|
||||
text = NodeModelUtils.getNode(c).text
|
||||
text = text.trim()
|
||||
return text
|
||||
}
|
||||
c = c.eContainer
|
||||
}
|
||||
return text
|
||||
}
|
||||
override text(IEObjectDescription ele) {
|
||||
return super.text(ele);
|
||||
}
|
||||
|
||||
override image(IEObjectDescription ele) {
|
||||
ele.EClass.name + '.gif'
|
||||
}
|
||||
}
|
@ -0,0 +1,248 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ui.labeling
|
||||
|
||||
import com.google.inject.Inject
|
||||
import java.util.Iterator
|
||||
import org.eclipse.emf.common.util.EList
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider
|
||||
import org.eclipse.jface.viewers.StyledString
|
||||
import org.eclipse.xtext.naming.IQualifiedNameProvider
|
||||
import org.eclipse.xtext.naming.QualifiedName
|
||||
import org.eclipse.xtext.ui.label.DefaultEObjectLabelProvider
|
||||
import ghidra.xtext.sleigh.sleigh.DefineSym
|
||||
import ghidra.xtext.sleigh.sleigh.SUBTABLESYM
|
||||
import ghidra.xtext.sleigh.sleigh.VARSYM
|
||||
import ghidra.xtext.sleigh.sleigh.baseconstructor
|
||||
import ghidra.xtext.sleigh.sleigh.constraint
|
||||
import ghidra.xtext.sleigh.sleigh.constructprint
|
||||
import ghidra.xtext.sleigh.sleigh.contextfielddef
|
||||
import ghidra.xtext.sleigh.sleigh.fielddef
|
||||
import ghidra.xtext.sleigh.sleigh.integerValue
|
||||
import ghidra.xtext.sleigh.sleigh.macroDefine
|
||||
import ghidra.xtext.sleigh.sleigh.printpiece
|
||||
import ghidra.xtext.sleigh.sleigh.subconstructor
|
||||
import ghidra.xtext.sleigh.sleigh.varattach
|
||||
import ghidra.xtext.sleigh.sleigh.varnodedef
|
||||
|
||||
import static extension org.eclipse.emf.ecore.util.EcoreUtil.*
|
||||
import static extension org.eclipse.xtext.EcoreUtil2.*
|
||||
|
||||
/**
|
||||
* Provides labels for EObjects.
|
||||
*
|
||||
* See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider
|
||||
*/
|
||||
class SleighLabelProvider extends DefaultEObjectLabelProvider {
|
||||
@Inject
|
||||
new(AdapterFactoryLabelProvider delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
@Inject
|
||||
private IQualifiedNameProvider nameProvider;
|
||||
|
||||
QualifiedName qn
|
||||
|
||||
EObject model
|
||||
|
||||
Iterator<varattach> varatt
|
||||
|
||||
def String text(EObject eObject) {
|
||||
qn = nameProvider.getFullyQualifiedName(eObject);
|
||||
if(qn == null) {
|
||||
return getObjectText(eObject);
|
||||
}
|
||||
|
||||
return qn.toString();
|
||||
}
|
||||
|
||||
def String getObjectText(EObject element) {
|
||||
switch element {
|
||||
macroDefine:
|
||||
element.defineType // + element.definename.name + " = " + element.value
|
||||
VARSYM:
|
||||
element.name + " : " + getSizeStr((element.eContainer.eContainer as varnodedef).size)
|
||||
SUBTABLESYM:
|
||||
element.name
|
||||
contextfielddef:
|
||||
element.name
|
||||
fielddef:
|
||||
element.name
|
||||
subconstructor:
|
||||
doGetText(element.tableName) + ':'
|
||||
baseconstructor:
|
||||
':' + doGetText(element.print)
|
||||
constructprint:
|
||||
formatString(element.printpieces)
|
||||
constraint:
|
||||
element.eClass.baseName
|
||||
default: {
|
||||
//System.out.println(element.class.simpleName)
|
||||
element.class.simpleName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String possible;
|
||||
|
||||
def getfielddefText(fielddef element) {
|
||||
// find all var attaches and display possible names
|
||||
var len = getVarAttachesForElement(element)
|
||||
return convertToStyledString('field ' + element.name).append(
|
||||
" " + len + " " + ' (' + element.start.value + ',' + element.end.value + ')' +
|
||||
(if(element.isSigned()) ' signed' else ''), StyledString::QUALIFIER_STYLER).append("\n\n" + possible);
|
||||
}
|
||||
|
||||
def getcontextfielddefText(contextfielddef element) {
|
||||
// find all var attaches and display possible names
|
||||
var len = getVarAttachesForElement(element)
|
||||
// is in a context, put out the name
|
||||
return convertToStyledString('context ' + element.name).append(
|
||||
" " + len + " " + ' (' + element.start.value + ',' + element.end.value + ')' +
|
||||
(if(element.isSigned()) ' signed' else ''), StyledString::QUALIFIER_STYLER).append("\n\n" + possible);
|
||||
}
|
||||
|
||||
protected def String getVarAttachesForElement(EObject element) {
|
||||
model = element.eResource.contents.get(0);
|
||||
varatt = model.eAllContents.filter(typeof(varattach));
|
||||
possible = "";
|
||||
var len = "";
|
||||
while (varatt.hasNext) {
|
||||
var next = varatt.next;
|
||||
var vlist = next.valuelist.valuelist.listIterator;
|
||||
while (vlist.hasNext) {
|
||||
var v = vlist.next;
|
||||
if (v.sym.equals(element)) {
|
||||
var viter = next.vlist.varDefList.iterator;
|
||||
possible = "attached to: "
|
||||
while (viter.hasNext) {
|
||||
var varname = viter.next;
|
||||
var vref = varname.varpart;
|
||||
if (vref != null) {
|
||||
var vdef = vref.getContainerOfType(typeof(varnodedef));
|
||||
if (vdef != null) {
|
||||
var size = vdef.size.value;
|
||||
len = size; // works even if is a $Define
|
||||
}
|
||||
possible = possible + vref.name + " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
len
|
||||
}
|
||||
|
||||
def getDefineSymText(DefineSym element) {
|
||||
// find all var attaches and display possible names
|
||||
var retStr = "";
|
||||
model = element.eResource.contents.get(0);
|
||||
var macDefs = model.eAllContents.filter(typeof(macroDefine));
|
||||
possible = "";
|
||||
var len = "";
|
||||
while (macDefs.hasNext) {
|
||||
var next = macDefs.next;
|
||||
if (next.defineType.equals("@define")) {
|
||||
if (next.definename.name == element.name) {
|
||||
retStr = retStr + next.value + "\r\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
if (retStr.length == 0) {
|
||||
return super.doGetText(element);
|
||||
}
|
||||
return retStr;
|
||||
}
|
||||
|
||||
override protected doGetText(Object element) {
|
||||
if(element == null) return null;
|
||||
// System.out.println("Label:" + element.class.baseName + " : " + element);
|
||||
switch element {
|
||||
macroDefine:
|
||||
element.defineType // + element.definename.name + " = " + element.value
|
||||
VARSYM:
|
||||
element.name + " : " + getSizeStr((element.getContainerOfType(typeof(varnodedef))).size)
|
||||
SUBTABLESYM:
|
||||
element.name
|
||||
contextfielddef:
|
||||
getcontextfielddefText(element)
|
||||
fielddef:
|
||||
getfielddefText(element)
|
||||
subconstructor:
|
||||
doGetText(element.tableName) + ':'
|
||||
baseconstructor:
|
||||
':' + doGetText(element.print)
|
||||
constructprint:
|
||||
formatString(element.printpieces)
|
||||
constraint:
|
||||
doGetText(element.sym)
|
||||
DefineSym:
|
||||
getDefineSymText(element)
|
||||
default:
|
||||
super.doGetText(element)
|
||||
}
|
||||
}
|
||||
|
||||
def getSizeStr(integerValue size) {
|
||||
if (size.value != null) {
|
||||
return size.value
|
||||
}
|
||||
if (size.sym != null) {
|
||||
return size.sym.getText
|
||||
}
|
||||
return "?"
|
||||
}
|
||||
|
||||
def getBaseName(Object element) {
|
||||
element.class.name.substring(element.class.name.lastIndexOf('.') + 1)
|
||||
}
|
||||
|
||||
def String formatString(EList<printpiece> list) {
|
||||
var str = "";
|
||||
var iter = list.iterator;
|
||||
while (iter.hasNext) {
|
||||
var piece = iter.next;
|
||||
if (piece.str == null) {
|
||||
if (piece.sym != null) {
|
||||
str += piece.sym.sym;
|
||||
} else {
|
||||
str = '{empty}'
|
||||
}
|
||||
} else {
|
||||
str += piece.str;
|
||||
}
|
||||
}
|
||||
str
|
||||
}
|
||||
|
||||
override protected doGetImage(Object element) {
|
||||
// icons are stored in the 'icons' folder of this project.
|
||||
// when adding such a folder, don't forget to add it to the 'bin.includes' section in the build.properties
|
||||
switch element {
|
||||
// fielddef:
|
||||
// 'F-blue.png'
|
||||
// contextfielddef:
|
||||
// 'C-blue.png'
|
||||
// VARSYM:
|
||||
// 'F-blue.png'
|
||||
default:
|
||||
super.doGetImage(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,82 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ui.outline
|
||||
|
||||
import java.util.ArrayList
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.xtext.ui.editor.model.IXtextDocument
|
||||
import org.eclipse.xtext.ui.editor.outline.IOutlineNode
|
||||
import org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider
|
||||
import org.eclipse.xtext.util.concurrent.IUnitOfWork
|
||||
|
||||
/**
|
||||
* Customization of the default outline structure.
|
||||
*
|
||||
* See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#outline
|
||||
*/
|
||||
class SleighOutlineTreeProvider extends DefaultOutlineTreeProvider {
|
||||
|
||||
// This controls the size of the outline
|
||||
// Displaying the outline can be expensive
|
||||
// TODO: figure out performance issue, possibly carefully
|
||||
// building the outline based on Sleigh ideas not pure grammer
|
||||
|
||||
override createRoot(IXtextDocument document) {
|
||||
if (document.numberOfLines < 100) {
|
||||
super.createRoot(document);
|
||||
} else {
|
||||
new IOutlineNode() {
|
||||
|
||||
override getChildren() {
|
||||
new ArrayList<IOutlineNode>();
|
||||
}
|
||||
|
||||
override getFullTextRegion() {
|
||||
throw new UnsupportedOperationException("TODO: auto-generated method stub")
|
||||
}
|
||||
|
||||
override getImage() {
|
||||
return null
|
||||
}
|
||||
|
||||
override getParent() {
|
||||
return null
|
||||
}
|
||||
|
||||
override getSignificantTextRegion() {
|
||||
throw new UnsupportedOperationException("TODO: auto-generated method stub")
|
||||
}
|
||||
|
||||
override getText() {
|
||||
return "suppressed outline"
|
||||
}
|
||||
|
||||
override hasChildren() {
|
||||
return false
|
||||
}
|
||||
|
||||
override <T> getAdapter(Class<T> adapter) {
|
||||
throw new UnsupportedOperationException("TODO: auto-generated method stub")
|
||||
}
|
||||
|
||||
override <Result> readOnly(IUnitOfWork<Result, EObject> work) {
|
||||
throw new UnsupportedOperationException("TODO: auto-generated method stub")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,323 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.ui.quickfix
|
||||
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil
|
||||
import org.eclipse.xtext.EcoreUtil2
|
||||
import org.eclipse.xtext.diagnostics.Diagnostic
|
||||
import org.eclipse.xtext.resource.XtextResource
|
||||
import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider
|
||||
import org.eclipse.xtext.ui.editor.quickfix.Fix
|
||||
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor
|
||||
import org.eclipse.xtext.util.concurrent.IUnitOfWork
|
||||
import org.eclipse.xtext.validation.Issue
|
||||
import ghidra.xtext.sleigh.sleigh.Expression
|
||||
import ghidra.xtext.sleigh.sleigh.LOCALSYM
|
||||
import ghidra.xtext.sleigh.sleigh.Model
|
||||
import ghidra.xtext.sleigh.sleigh.SleighFactory
|
||||
import ghidra.xtext.sleigh.sleigh.VARSYM
|
||||
import ghidra.xtext.sleigh.sleigh.constraint
|
||||
import ghidra.xtext.sleigh.sleigh.constructor
|
||||
import ghidra.xtext.sleigh.sleigh.exprSym
|
||||
import ghidra.xtext.sleigh.sleigh.fielddef
|
||||
import ghidra.xtext.sleigh.sleigh.integerValue
|
||||
import ghidra.xtext.sleigh.sleigh.lhsvarnode
|
||||
import ghidra.xtext.sleigh.sleigh.localDefine
|
||||
import ghidra.xtext.sleigh.sleigh.macroOrPcode
|
||||
import ghidra.xtext.sleigh.sleigh.statement
|
||||
import ghidra.xtext.sleigh.sleigh.tokendef
|
||||
import ghidra.xtext.sleigh.sleigh.varattach
|
||||
import ghidra.xtext.sleigh.sleigh.varnodedef
|
||||
import ghidra.xtext.sleigh.sleigh.vnoderef
|
||||
|
||||
import static extension org.eclipse.emf.ecore.util.EcoreUtil.*
|
||||
import static extension org.eclipse.xtext.EcoreUtil2.*
|
||||
|
||||
/**
|
||||
* Custom quickfixes.
|
||||
*
|
||||
* See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#quick-fixes
|
||||
*/
|
||||
class SleighQuickfixProvider extends DefaultQuickfixProvider {
|
||||
|
||||
@Fix(Diagnostic::LINKING_DIAGNOSTIC)
|
||||
def void createMissingVariable(Issue issue, IssueResolutionAcceptor acceptor) {
|
||||
var message = issue.message;
|
||||
var to = getToName(message);
|
||||
var linkName = getLinkName(message);
|
||||
var sname = macroOrPcode.simpleName.toString();
|
||||
switch (to) {
|
||||
case macroOrPcode.simpleName:
|
||||
missingPseudoOp(issue, acceptor, to, linkName)
|
||||
case lhsvarnode.simpleName:
|
||||
createLocalVarnode(issue, acceptor, to, linkName)
|
||||
case EObject.simpleName:
|
||||
missingEObjectLink(issue, acceptor, to, linkName)
|
||||
}
|
||||
}
|
||||
|
||||
def missingPseudoOp(Issue issue, IssueResolutionAcceptor acceptor, String to, String linkName) {
|
||||
acceptor.accept(
|
||||
issue,
|
||||
"Create pcodeop '" + linkName + "'",
|
||||
"Create pcodeop '" + linkName + "'",
|
||||
"",
|
||||
[ element, context |
|
||||
val currentEntity = EcoreUtil2.getContainerOfType(element,constructor)
|
||||
val model = currentEntity.eContainer as Model
|
||||
val newdef = SleighFactory::eINSTANCE.createpcodeopdef() => [
|
||||
ops.add(SleighFactory::eINSTANCE.createUSEROPSYM() => [
|
||||
name = context.xtextDocument.get(issue.offset, issue.length)
|
||||
])
|
||||
];
|
||||
model.elements.add(model.elements.indexOf(currentEntity), newdef)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
def missingEObjectLink(Issue issue, IssueResolutionAcceptor acceptor, String to, String linkName) {
|
||||
val modificationContext = getModificationContextFactory().createModificationContext(issue);
|
||||
val xtextDocument = modificationContext.getXtextDocument();
|
||||
xtextDocument.readOnly(
|
||||
new IUnitOfWork.Void<XtextResource>() {
|
||||
|
||||
override process(XtextResource state) throws Exception {
|
||||
var cause = state.getResourceSet().getEObject(issue.getUriToProblem(), false);
|
||||
if (cause instanceof constraint) {
|
||||
missingConstraint(issue, acceptor, to, linkName, cause)
|
||||
missingSubConstructor(issue, acceptor, to, linkName, cause)
|
||||
}
|
||||
// switch cause {
|
||||
// case constraint:
|
||||
//
|
||||
// default: {
|
||||
// var x = cause
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
def missingConstraint(Issue issue, IssueResolutionAcceptor acceptor, String to, String linkName, EObject cause) {
|
||||
acceptor.accept(
|
||||
issue,
|
||||
"Create fieldef '" + linkName + "'",
|
||||
"Create fieldef '" + linkName + "'",
|
||||
"",
|
||||
[ element, context |
|
||||
var root = EcoreUtil2.getRootContainer(cause) as Model;
|
||||
// find fielddef
|
||||
var tokendefs = root.getAllContentsOfType(typeof(tokendef))
|
||||
if(tokendefs.size <= 0) return;
|
||||
var tokendef = tokendefs.get(0);
|
||||
|
||||
// if found, put at end
|
||||
val newfielddef = SleighFactory::eINSTANCE.createfielddef() => [
|
||||
name = linkName
|
||||
// TODO: try to figure out start/end
|
||||
// TODO: ask start / end
|
||||
start = SleighFactory.eINSTANCE.createintegerValue() => [
|
||||
value = '0';
|
||||
]
|
||||
end = SleighFactory.eINSTANCE.createintegerValue() => [
|
||||
value = '0';
|
||||
]
|
||||
];
|
||||
// add
|
||||
tokendef.fields.tokens.add(newfielddef)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
def missingSubConstructor(Issue issue, IssueResolutionAcceptor acceptor, String to, String linkName, EObject cause) {
|
||||
acceptor.accept(
|
||||
issue,
|
||||
"Create SubConstruct '" + linkName + "'",
|
||||
"Create SubConstruct '" + linkName + "'",
|
||||
"",
|
||||
[ element, context |
|
||||
var model = cause.rootContainer as Model;
|
||||
|
||||
var container = EcoreUtil2.getContainerOfType(cause, constructor)
|
||||
|
||||
// create subconstructor template
|
||||
val sub = SleighFactory::eINSTANCE.createsubconstructor() => [
|
||||
tableName = SleighFactory.eINSTANCE.createSUBTABLESYM() => [
|
||||
name = linkName;
|
||||
]
|
||||
print = SleighFactory.eINSTANCE.createconstructprint() => [
|
||||
var pp = SleighFactory.eINSTANCE.createprintpiece() => [
|
||||
str = ""
|
||||
]
|
||||
printpieces.add(pp)
|
||||
is = SleighFactory.eINSTANCE.createisKeyword() => []
|
||||
]
|
||||
match = SleighFactory.eINSTANCE.createpequation() => [
|
||||
constraints = SleighFactory.eINSTANCE.createconstraint() => [
|
||||
isepsilon = true
|
||||
]
|
||||
]
|
||||
body = SleighFactory.eINSTANCE.creatertlbody() => [
|
||||
unimpl = true
|
||||
]
|
||||
];
|
||||
// add before this instance
|
||||
model.elements.add(model.elements.indexOf(container), sub)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
def createLocalVarnode(Issue issue, IssueResolutionAcceptor acceptor, String to, String linkName) {
|
||||
acceptor.accept(
|
||||
issue,
|
||||
"Create local '" + linkName + "'",
|
||||
"Create local '" + linkName + "'",
|
||||
"",
|
||||
[ element, context |
|
||||
// find size of first element if it can
|
||||
val s = findElementSize(element);
|
||||
if (s == null) {
|
||||
val newdef = SleighFactory::eINSTANCE.createassignSym() => [
|
||||
local = SleighFactory::eINSTANCE.createlocalDefine() => [
|
||||
sym = SleighFactory.eINSTANCE.createLOCALSYM() => [
|
||||
name = linkName;
|
||||
]
|
||||
]
|
||||
];
|
||||
element.replace(newdef);
|
||||
} else {
|
||||
val newdef = SleighFactory::eINSTANCE.createassignSym() => [
|
||||
local = SleighFactory::eINSTANCE.createlocalDefine() => [
|
||||
sym = SleighFactory.eINSTANCE.createLOCALSYM() => [
|
||||
name = linkName;
|
||||
]
|
||||
size = SleighFactory.eINSTANCE.createintegerValue() => [
|
||||
value = s.value;
|
||||
sym = s.sym;
|
||||
]
|
||||
]
|
||||
];
|
||||
element.replace(newdef);
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
def integerValue findElementSize(EObject element) {
|
||||
val currentEntity = EcoreUtil2.getContainerOfType(element, statement)
|
||||
val rhs = currentEntity.rhs;
|
||||
val s = findSize(rhs);
|
||||
return s;
|
||||
}
|
||||
|
||||
var integerValue len;
|
||||
|
||||
def integerValue findSize(Expression rhs) {
|
||||
len = null;
|
||||
if (rhs instanceof exprSym) {
|
||||
return getExprSymLength(rhs);
|
||||
}
|
||||
var vlist = rhs.getAllContentsOfType(typeof(exprSym));
|
||||
vlist.forEach [ it |
|
||||
getExprSymLength(it)
|
||||
]
|
||||
return len;
|
||||
}
|
||||
|
||||
def getExprSymLength(exprSym sym) {
|
||||
var node = sym.vnode;
|
||||
switch node {
|
||||
VARSYM: {
|
||||
var def = node.getContainerOfType(typeof(varnodedef));
|
||||
if (def != null && def.size != null) {
|
||||
if (len == null) {
|
||||
len = def.size;
|
||||
}
|
||||
} else if (len != def.size) {
|
||||
len = null;
|
||||
}
|
||||
}
|
||||
fielddef: {
|
||||
len = findVarAttachLen(node);
|
||||
}
|
||||
LOCALSYM: {
|
||||
var ldef = node.getContainerOfType(typeof(localDefine));
|
||||
if (ldef != null && ldef.size != null) {
|
||||
if (len == null) {
|
||||
len = ldef.size;
|
||||
}
|
||||
} else if (len != ldef.size) {
|
||||
len = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def integerValue findVarAttachLen(fielddef fdef) {
|
||||
// find all var attaches and display possible names
|
||||
var model = fdef.eResource.contents.get(0);
|
||||
var varatt = model.eAllContents.filter(typeof(varattach));
|
||||
while (varatt.hasNext) {
|
||||
var next = varatt.next;
|
||||
var vlist = next.valuelist.valuelist.listIterator;
|
||||
while (vlist.hasNext) {
|
||||
var v = vlist.next;
|
||||
if (v.sym.equals(fdef)) {
|
||||
var viter = next.vlist.varDefList.iterator;
|
||||
while (viter.hasNext) {
|
||||
var varname = viter.next;
|
||||
var vref = varname.varpart;
|
||||
if (vref != null) {
|
||||
var vdef = vref.getContainerOfType(typeof(varnodedef));
|
||||
if (vdef != null) {
|
||||
var size = vdef.size;
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
def findVnodeSize(vnoderef ref) {
|
||||
System.out.println(' printit ' + ref.ID);
|
||||
}
|
||||
|
||||
def String getLinkName(String str) {
|
||||
var end = str.lastIndexOf('\'')
|
||||
var start = str.lastIndexOf('\'', end - 1)
|
||||
return str.substring(start + 1, end)
|
||||
}
|
||||
|
||||
def String getToName(String str) {
|
||||
val refString = "reference to ";
|
||||
|
||||
var index = str.indexOf(refString);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
}
|
||||
var start = index + refString.length;
|
||||
var refStr = str.substring(start);
|
||||
refStr = refStr.substring(0, refStr.indexOf(' '));
|
||||
return refStr;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.emf.mwe2.launch.Mwe2LaunchConfigurationType">
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/ghidra.xtext.sleigh"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/ghidra.xtext.sleigh" type="4"/> <item path="/ghidra.xtext.sleigh.ide" type="4"/> <item path="/ghidra.xtext.sleigh.ui" type="4"/> <item path="/ghidra.xtext.sleigh.feature" type="4"/> <item path="/ghidra.xtext.sleigh.tests" type="4"/> <item path="/ghidra.xtext.sleigh.ui.tests" type="4"/> <item path="/ghidra.xtext.sleigh.tests" type="4"/> <item path="/ghidra.xtext.sleigh.ui.tests" type="4"/> ;</resources>}"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="ghidra.xtext.sleigh.GenerateSleigh"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="ghidra.xtext.sleigh"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx512m"/>
|
||||
</launchConfiguration>
|
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.pde.ui.RuntimeWorkbench">
|
||||
<booleanAttribute key="append.args" value="true"/>
|
||||
<booleanAttribute key="askclear" value="true"/>
|
||||
<booleanAttribute key="automaticAdd" value="true"/>
|
||||
<booleanAttribute key="automaticValidate" value="false"/>
|
||||
<stringAttribute key="bad_container_name" value="/ghidra.xtext.sleigh/.launch/"/>
|
||||
<stringAttribute key="bootstrap" value=""/>
|
||||
<stringAttribute key="checked" value="[NONE]"/>
|
||||
<booleanAttribute key="clearConfig" value="false"/>
|
||||
<booleanAttribute key="clearws" value="false"/>
|
||||
<booleanAttribute key="clearwslog" value="false"/>
|
||||
<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/Launch Runtime Eclipse"/>
|
||||
<booleanAttribute key="default" value="true"/>
|
||||
<booleanAttribute key="includeOptional" value="true"/>
|
||||
<stringAttribute key="location" value="${workspace_loc}/../runtime-EclipseXtext"/>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl}"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -Xmx512m"/>
|
||||
<stringAttribute key="pde.version" value="3.3"/>
|
||||
<stringAttribute key="product" value="org.eclipse.platform.ide"/>
|
||||
<booleanAttribute key="show_selected_only" value="false"/>
|
||||
<stringAttribute key="templateConfig" value="${target_home}/configuration/config.ini"/>
|
||||
<booleanAttribute key="tracing" value="false"/>
|
||||
<booleanAttribute key="useDefaultConfig" value="true"/>
|
||||
<booleanAttribute key="useDefaultConfigArea" value="true"/>
|
||||
<booleanAttribute key="useProduct" value="true"/>
|
||||
<booleanAttribute key="usefeatures" value="false"/>
|
||||
</launchConfiguration>
|
@ -0,0 +1,31 @@
|
||||
Manifest-Version: 1.0
|
||||
Automatic-Module-Name: ghidra.xtext.sleigh
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: ghidra.xtext.sleigh
|
||||
Bundle-Vendor: My Company
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-SymbolicName: ghidra.xtext.sleigh; singleton:=true
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: org.eclipse.xtext,
|
||||
org.eclipse.xtext.xbase,
|
||||
org.eclipse.equinox.common;bundle-version="3.5.0",
|
||||
org.eclipse.emf.ecore,
|
||||
org.eclipse.xtext.xbase.lib;bundle-version="2.14.0",
|
||||
org.eclipse.xtext.util,
|
||||
org.eclipse.emf.common,
|
||||
org.eclipse.xtend.lib;bundle-version="2.14.0",
|
||||
org.antlr.runtime;bundle-version="[3.2.0,3.2.1)"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||
Export-Package: ghidra.xtext.sleigh.formatting2,
|
||||
ghidra.xtext.sleigh,
|
||||
ghidra.xtext.sleigh.sleigh.impl,
|
||||
ghidra.xtext.sleigh.validation,
|
||||
ghidra.xtext.sleigh.scoping,
|
||||
ghidra.xtext.sleigh.sleigh,
|
||||
ghidra.xtext.sleigh.serializer,
|
||||
ghidra.xtext.sleigh.parser.antlr.internal,
|
||||
ghidra.xtext.sleigh.services,
|
||||
ghidra.xtext.sleigh.sleigh.util,
|
||||
ghidra.xtext.sleigh.generator,
|
||||
ghidra.xtext.sleigh.parser.antlr
|
||||
Import-Package: org.apache.log4j
|
@ -0,0 +1,20 @@
|
||||
source.. = src/,\
|
||||
src-gen/,\
|
||||
xtend-gen/
|
||||
bin.includes = model/generated/,\
|
||||
.,\
|
||||
META-INF/,\
|
||||
plugin.xml
|
||||
bin.excludes = **/*.mwe2,\
|
||||
**/*.xtend
|
||||
additional.bundles = org.eclipse.xtext.xbase,\
|
||||
org.eclipse.xtext.common.types,\
|
||||
org.eclipse.xtext.xtext.generator,\
|
||||
org.eclipse.emf.codegen.ecore,\
|
||||
org.eclipse.emf.mwe.utils,\
|
||||
org.eclipse.emf.mwe2.launch,\
|
||||
org.eclipse.emf.mwe2.lib,\
|
||||
org.objectweb.asm,\
|
||||
org.apache.commons.logging,\
|
||||
org.apache.log4j,\
|
||||
com.ibm.icu
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.0"?>
|
||||
<plugin>
|
||||
<extension point="org.eclipse.emf.ecore.generated_package">
|
||||
<package
|
||||
uri = "http://www.xtext.ghidra/sleigh/Sleigh"
|
||||
class = "ghidra.xtext.sleigh.sleigh.SleighPackage"
|
||||
genModel = "model/generated/Sleigh.genmodel" />
|
||||
</extension>
|
||||
</plugin>
|
@ -0,0 +1,58 @@
|
||||
module ghidra.xtext.sleigh.GenerateSleigh
|
||||
|
||||
import org.eclipse.xtext.xtext.generator.*
|
||||
import org.eclipse.xtext.xtext.generator.model.project.*
|
||||
|
||||
var rootPath = ".."
|
||||
|
||||
Workflow {
|
||||
|
||||
component = XtextGenerator {
|
||||
configuration = {
|
||||
project = StandardProjectConfig {
|
||||
baseName = "ghidra.xtext.sleigh"
|
||||
rootPath = rootPath
|
||||
runtimeTest = {
|
||||
enabled = true
|
||||
}
|
||||
eclipsePlugin = {
|
||||
enabled = true
|
||||
}
|
||||
eclipsePluginTest = {
|
||||
enabled = true
|
||||
}
|
||||
createEclipseMetaData = true
|
||||
}
|
||||
code = {
|
||||
encoding = "UTF-8"
|
||||
lineDelimiter = "\n"
|
||||
fileHeader = "/*\n * generated by Xtext \${version}\n */"
|
||||
}
|
||||
}
|
||||
language = StandardLanguage {
|
||||
name = "ghidra.xtext.sleigh.Sleigh"
|
||||
fileExtensions = "slaspec,sinc"
|
||||
|
||||
serializer = {
|
||||
generateStub = false
|
||||
}
|
||||
validator = {
|
||||
// composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
|
||||
// Generates checks for @Deprecated grammar annotations, an IssueProvider and a corresponding PropertyPage
|
||||
generateDeprecationValidation = true
|
||||
}
|
||||
fragment = ui.labeling.LabelProviderFragment2 {}
|
||||
|
||||
fragment = formatting.Formatter2Fragment2 {}
|
||||
|
||||
fragment = ui.quickfix.QuickfixProviderFragment2 {}
|
||||
|
||||
// enable rename refactoring
|
||||
fragment = ui.refactoring.RefactorElementNameFragment2 {}
|
||||
|
||||
junitSupport = {
|
||||
junitVersion = "5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,23 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh
|
||||
|
||||
|
||||
/**
|
||||
* Use this class to register components to be used at runtime / without the Equinox extension registry.
|
||||
*/
|
||||
class SleighRuntimeModule extends AbstractSleighRuntimeModule {
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh
|
||||
|
||||
|
||||
/**
|
||||
* Initialization support for running Xtext languages without Equinox extension registry.
|
||||
*/
|
||||
class SleighStandaloneSetup extends SleighStandaloneSetupGenerated {
|
||||
|
||||
def static void doSetup() {
|
||||
new SleighStandaloneSetup().createInjectorAndDoEMFRegistration()
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.converter;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Map;
|
||||
|
||||
import org.antlr.runtime.Token;
|
||||
import org.antlr.runtime.TokenSource;
|
||||
import org.eclipse.xtext.AbstractRule;
|
||||
import org.eclipse.xtext.conversion.ValueConverterException;
|
||||
import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter;
|
||||
import org.eclipse.xtext.nodemodel.INode;
|
||||
import org.eclipse.xtext.parser.antlr.ITokenDefProvider;
|
||||
import org.eclipse.xtext.parser.antlr.Lexer;
|
||||
import org.eclipse.xtext.util.Strings;
|
||||
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class IntValueConverter extends AbstractLexerBasedConverter<BigInteger> {
|
||||
|
||||
@Override
|
||||
protected String toEscapedString(BigInteger value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertValidValue(BigInteger value) {
|
||||
super.assertValidValue(value);
|
||||
if (value.compareTo(BigInteger.ZERO) < 0)
|
||||
throw new ValueConverterException(getRuleName() + "-value may not be negative (value: " + value + ").", null, null);
|
||||
}
|
||||
|
||||
public BigInteger toValue(String string, INode node) {
|
||||
if (Strings.isEmpty(string))
|
||||
throw new ValueConverterException("Couldn't convert empty string to an int value.", node, null);
|
||||
try {
|
||||
String parseString = string;
|
||||
int radix = 10;
|
||||
if (parseString.startsWith("0x") || parseString.startsWith("0X")) {
|
||||
parseString = string.substring(2);
|
||||
radix=16;
|
||||
}
|
||||
if (parseString.startsWith("0b") || parseString.startsWith("0B")) {
|
||||
parseString = string.substring(2);
|
||||
radix=2;
|
||||
}
|
||||
return new BigInteger(parseString,radix);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ValueConverterException("Couldn't convert '" + string + "' to a BigInteger value.", node, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.converter;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.eclipse.xtext.common.services.DefaultTerminalConverters;
|
||||
import org.eclipse.xtext.conversion.IValueConverter;
|
||||
import org.eclipse.xtext.conversion.ValueConverter;
|
||||
import org.eclipse.xtext.conversion.ValueConverterException;
|
||||
import org.eclipse.xtext.conversion.impl.INTValueConverter;
|
||||
import org.eclipse.xtext.nodemodel.INode;
|
||||
import org.eclipse.xtext.util.Strings;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class SleighValueConverter extends DefaultTerminalConverters {
|
||||
|
||||
@Inject
|
||||
private IntValueConverter hexValueConverter;
|
||||
|
||||
@ValueConverter(rule = "HEXVAL")
|
||||
public IValueConverter<BigInteger> HEXVAL() {
|
||||
return hexValueConverter;
|
||||
}
|
||||
|
||||
@Inject
|
||||
private IntValueConverter numValueConverter;
|
||||
|
||||
@ValueConverter(rule = "NUMVAL")
|
||||
public IValueConverter<BigInteger> NUMVAL() {
|
||||
return numValueConverter;
|
||||
}
|
||||
|
||||
@Inject
|
||||
private IntValueConverter binValueConverter;
|
||||
|
||||
@ValueConverter(rule = "BINVAL")
|
||||
public IValueConverter<BigInteger> BINVAL() {
|
||||
return binValueConverter;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,32 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.generator
|
||||
|
||||
import org.eclipse.emf.ecore.resource.Resource
|
||||
import org.eclipse.xtext.generator.AbstractGenerator
|
||||
import org.eclipse.xtext.generator.IFileSystemAccess2
|
||||
import org.eclipse.xtext.generator.IGeneratorContext
|
||||
|
||||
/**
|
||||
* Generates code from your model files on save.
|
||||
*
|
||||
* See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
|
||||
*/
|
||||
class SleighGenerator extends AbstractGenerator {
|
||||
|
||||
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
|
||||
}
|
||||
}
|
@ -0,0 +1,237 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.scoping
|
||||
|
||||
|
||||
import com.google.common.base.Function
|
||||
import com.google.common.base.Predicate
|
||||
import java.util.ArrayList
|
||||
import java.util.List
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.ecore.EReference
|
||||
import org.eclipse.xtext.naming.QualifiedName
|
||||
import org.eclipse.xtext.resource.IEObjectDescription
|
||||
import org.eclipse.xtext.scoping.IScope
|
||||
import org.eclipse.xtext.scoping.Scopes
|
||||
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider
|
||||
import org.eclipse.xtext.scoping.impl.FilteringScope
|
||||
import org.eclipse.xtext.scoping.impl.ScopeBasedSelectable
|
||||
import org.eclipse.xtext.scoping.impl.SelectableBasedScope
|
||||
import ghidra.xtext.sleigh.sleigh.LOCALSYM
|
||||
import ghidra.xtext.sleigh.sleigh.aliasSym
|
||||
import ghidra.xtext.sleigh.sleigh.assignSym
|
||||
import ghidra.xtext.sleigh.sleigh.constraint
|
||||
import ghidra.xtext.sleigh.sleigh.constructor
|
||||
import ghidra.xtext.sleigh.sleigh.contextblock
|
||||
import ghidra.xtext.sleigh.sleigh.contextentry
|
||||
import ghidra.xtext.sleigh.sleigh.exportedSym
|
||||
import ghidra.xtext.sleigh.sleigh.exprSym
|
||||
import ghidra.xtext.sleigh.sleigh.globalLoc
|
||||
import ghidra.xtext.sleigh.sleigh.macrodef
|
||||
import ghidra.xtext.sleigh.sleigh.pexprSym
|
||||
import ghidra.xtext.sleigh.sleigh.rtlbody
|
||||
import ghidra.xtext.sleigh.sleigh.rtlmid
|
||||
import ghidra.xtext.sleigh.sleigh.statement
|
||||
import ghidra.xtext.sleigh.sleigh.xrtl
|
||||
|
||||
import static extension org.eclipse.xtext.EcoreUtil2.*
|
||||
|
||||
/**
|
||||
* This class contains custom scoping description.
|
||||
*
|
||||
* See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
|
||||
* on how and when to use it.
|
||||
*/
|
||||
public class SleighScopeProvider extends AbstractDeclarativeScopeProvider {
|
||||
|
||||
override getScope(EObject context, EReference ref) {
|
||||
//System.out.println(context.class.name + " - " + ref.name + " : ")
|
||||
var scope = super.getScope(context, ref)
|
||||
//System.out.println(" " + scope.toString)
|
||||
return scope
|
||||
}
|
||||
|
||||
def IScope scope_assignSym_symref(assignSym context, EReference eReference) {
|
||||
var localScope = context.eContainer.symbolsDefinedBefore(context)
|
||||
var cont = context.getContainerOfType(typeof(rtlbody));
|
||||
var superscope = super.getDelegate().getScope(cont, eReference)
|
||||
return createFilteredLocalScope(superscope, localScope, eReference)
|
||||
}
|
||||
|
||||
def IScope scope_exprSym_vnode(exprSym context, EReference eReference) {
|
||||
var localScope = context.eContainer.symbolsDefinedBefore(context)
|
||||
var cont = context.getContainerOfType(typeof(rtlbody));
|
||||
var superscope = super.getDelegate().getScope(cont, eReference)
|
||||
return createFilteredLocalScope(superscope, localScope, eReference)
|
||||
}
|
||||
|
||||
def IScope scope_exportedSym_symref(exportedSym context, EReference eReference) {
|
||||
var localScope = context.eContainer.symbolsDefinedBefore(context)
|
||||
var cont = context.getContainerOfType(typeof(rtlbody));
|
||||
var superscope = super.getDelegate().getScope(cont, eReference)
|
||||
createFilteredLocalScope(superscope, localScope, eReference)
|
||||
}
|
||||
|
||||
|
||||
def IScope scope_pexprSym_sym(pexprSym context, EReference eReference) {
|
||||
var localScope = context.eContainer.symbolsDefinedBefore(context)
|
||||
var cont = context.getContainerOfType(typeof(constructor));
|
||||
var superscope = super.getDelegate().getScope(cont, eReference)
|
||||
createFilteredLocalScope(superscope, localScope, eReference)
|
||||
}
|
||||
|
||||
|
||||
def IScope scope_constraint_sym(constraint context, EReference eReference) {
|
||||
var cont = context.getContainerOfType(typeof(constructor));
|
||||
var superscope = super.getDelegate().getScope(cont, eReference)
|
||||
var scope= createFilteredLocalScope(superscope, IScope.NULLSCOPE, eReference)
|
||||
scope
|
||||
}
|
||||
|
||||
def IScope scope_aliasSym_symref(aliasSym context, EReference eReference) {
|
||||
var cont = context.getContainerOfType(typeof(constructor));
|
||||
var localScope = printPieceScope(cont,IScope.NULLSCOPE);
|
||||
localScope
|
||||
}
|
||||
|
||||
def IScope scope_contextentry_lhs(contextentry context, EReference eReference) {
|
||||
var cont = context.getContainerOfType(typeof(constructor));
|
||||
var localScope = printPieceScope(cont,IScope.NULLSCOPE);
|
||||
var superscope = super.getDelegate().getScope(cont, eReference)
|
||||
createFilteredLocalScope(superscope, localScope, eReference)
|
||||
}
|
||||
|
||||
def IScope scope_globalLoc_tsym(globalLoc context, EReference eReference) {
|
||||
var cont = context.getContainerOfType(typeof(constructor));
|
||||
var localScope = printPieceScope(cont,IScope.NULLSCOPE);
|
||||
var superscope = super.getDelegate().getScope(cont, eReference)
|
||||
createFilteredLocalScope(superscope, localScope, eReference)
|
||||
}
|
||||
|
||||
def IScope createFilteredLocalScope(IScope supscope, IScope localScope, EReference eReference) {
|
||||
var filtscope = new FilteringScope(supscope, new Predicate<IEObjectDescription>() {
|
||||
override apply(IEObjectDescription input) {
|
||||
val sym = input.getEObjectOrProxy()
|
||||
var notAliasOrLocal = !((sym instanceof LOCALSYM) || (sym instanceof aliasSym))
|
||||
return notAliasOrLocal
|
||||
}
|
||||
});
|
||||
|
||||
// Do scope in reverse, aliasSyms are just and alias, choose global scope over alias
|
||||
// The global scope has all LOCALSYM and aliasSym filtered out.
|
||||
// This may not be the most efficient method, but works.
|
||||
// Also for LOCALSYM, a Global sym may shadow it. Not quite right
|
||||
// Should really be (LOCALSYM, Global(outerscope), AliasSym)
|
||||
var scope = SelectableBasedScope.createScope(localScope, new ScopeBasedSelectable(filtscope),
|
||||
eReference.getEReferenceType(), false)
|
||||
scope
|
||||
}
|
||||
|
||||
def dispatch IScope symbolsDefinedBefore(EObject context, EObject o) {
|
||||
context.eContainer.symbolsDefinedBefore(o)
|
||||
}
|
||||
|
||||
def dispatch IScope symbolsDefinedBefore(macrodef context, EObject o) {
|
||||
Scopes::scopeFor(
|
||||
context.args.args,
|
||||
context.symbolsDefinedBefore(o.eContainer)
|
||||
)
|
||||
}
|
||||
|
||||
def dispatch IScope symbolsDefinedBefore(constructor s, EObject o) {
|
||||
var scope = Scopes::scopeFor(s.eContents)
|
||||
printPieceScope(s,scope);
|
||||
}
|
||||
|
||||
def dispatch IScope symbolsDefinedBefore(contextblock s, EObject o) {
|
||||
var scope = Scopes::scopeFor(s.eContents, s.eContainer.symbolsDefinedBefore(o.eContainer))
|
||||
var cont = s.getContainerOfType(typeof(constructor))
|
||||
printPieceScope(cont,scope);
|
||||
}
|
||||
|
||||
def dispatch IScope symbolsDefinedBefore(rtlbody b, EObject o) {
|
||||
var scope = Scopes::scopeFor(
|
||||
b.body.statements.rtllist.variablesDeclaredBefore(o)
|
||||
)
|
||||
var cont = b.getContainerOfType(typeof(constructor));
|
||||
printPieceScope(cont,scope);
|
||||
}
|
||||
|
||||
def dispatch IScope symbolsDefinedBefore(rtlmid b, EObject o) {
|
||||
return symbolsDefinedBefore(b.eContainer, o);
|
||||
}
|
||||
|
||||
def dispatch IScope symbolsDefinedBefore(xrtl b, EObject o) {
|
||||
var syms = b.statements.rtllist.variablesDeclaredBefore(null);
|
||||
if (b.additionalStatements != null) {
|
||||
syms.addAll(b.additionalStatements.rtllist.variablesDeclaredBefore(null))
|
||||
}
|
||||
var scope = Scopes::scopeFor(syms)
|
||||
var cont = b.getContainerOfType(typeof(constructor));
|
||||
printPieceScope(cont,scope);
|
||||
}
|
||||
|
||||
// Create a scope for all ID symbols in printpiece
|
||||
def printPieceScope(constructor cont, IScope outerScope) {
|
||||
if (cont == null) return outerScope
|
||||
var vars = cont.variablesDeclaredIn()
|
||||
var q = QualifiedName.wrapper(new Function<aliasSym, String>() {
|
||||
|
||||
override apply(aliasSym input) {
|
||||
if (input == null) return null;
|
||||
input.sym
|
||||
}
|
||||
})
|
||||
var localScope = Scopes.scopeFor(vars, q, outerScope)
|
||||
localScope
|
||||
}
|
||||
|
||||
// things in context block must be in printpieces
|
||||
def private variablesDeclaredIn(constructor b) {
|
||||
var iter = b.print.printpieces.iterator;
|
||||
var List<aliasSym> list = new ArrayList<aliasSym>();
|
||||
while (iter.hasNext) {
|
||||
var piece = iter.next;
|
||||
if (piece.sym instanceof aliasSym) {
|
||||
list.add(piece.sym)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
def private variablesDeclaredBefore(List<statement> list, EObject o) {
|
||||
var end = list.size - 1;
|
||||
if (o != null) {
|
||||
end = list.indexOf(o);
|
||||
}
|
||||
val sublist = list.subList(0, end + 1);
|
||||
var iter = sublist.iterator;
|
||||
var List<LOCALSYM> locList = new ArrayList<LOCALSYM>();
|
||||
while (iter.hasNext) {
|
||||
var obj = iter.next;
|
||||
if (obj instanceof statement) {
|
||||
var stmt = obj as statement;
|
||||
if (stmt.lhs != null && stmt.lhs.local != null && stmt.lhs.local.sym instanceof LOCALSYM) {
|
||||
locList.add(stmt.lhs.local.sym as LOCALSYM);
|
||||
}
|
||||
if (stmt.ldef != null && stmt.ldef.sym instanceof LOCALSYM) {
|
||||
locList.add(stmt.ldef.sym as LOCALSYM);
|
||||
}
|
||||
}
|
||||
}
|
||||
return locList;
|
||||
}
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.xtext.sleigh.validation
|
||||
|
||||
|
||||
|
||||
import java.util.HashMap
|
||||
import java.util.HashSet
|
||||
import org.eclipse.xtext.validation.Check
|
||||
import ghidra.xtext.sleigh.sleigh.Model
|
||||
import ghidra.xtext.sleigh.sleigh.SleighPackage
|
||||
import ghidra.xtext.sleigh.sleigh.VARSYM
|
||||
import ghidra.xtext.sleigh.sleigh.constraint
|
||||
import ghidra.xtext.sleigh.sleigh.contextdef
|
||||
import ghidra.xtext.sleigh.sleigh.contextfielddef
|
||||
import ghidra.xtext.sleigh.sleigh.fielddef
|
||||
import ghidra.xtext.sleigh.sleigh.tokendef
|
||||
import ghidra.xtext.sleigh.sleigh.vardef
|
||||
import ghidra.xtext.sleigh.sleigh.varnodedef
|
||||
|
||||
import static extension org.eclipse.emf.ecore.util.EcoreUtil.*
|
||||
import static extension org.eclipse.xtext.EcoreUtil2.*
|
||||
|
||||
/**
|
||||
* This class contains custom validation rules.
|
||||
*
|
||||
* See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation
|
||||
*/
|
||||
class SleighValidator extends AbstractSleighValidator {
|
||||
|
||||
var HashMap<Object,HashMap<String,HashSet<Object>>> typeMap;
|
||||
|
||||
@Check
|
||||
def void checkModelInitialize(Model m) {
|
||||
// model should be validated each time before the sub objects
|
||||
// are validated, so initialize the cache
|
||||
typeMap = new HashMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a name entry to the set of names->definitions Object map
|
||||
*/
|
||||
def addNameEntryToSet(HashMap<String, HashSet<Object>> map, String name, Object other) {
|
||||
var HashSet<Object> set = map.get(name);
|
||||
if (set == null) {
|
||||
set = new HashSet<Object>();
|
||||
map.put(name,set);
|
||||
}
|
||||
set.add(other)
|
||||
}
|
||||
|
||||
@Check
|
||||
def void checkTokenNameIsUnique(fielddef f) {
|
||||
if (checkDuplicate(f)) {
|
||||
warning("token field names have to be unique", SleighPackage.eINSTANCE.getfielddef_Name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
def boolean checkDuplicate(fielddef f) {
|
||||
var type = typeof(tokendef)
|
||||
var HashMap<String,HashSet<Object>> map = typeMap.get(type);
|
||||
if (map == null) {
|
||||
map = new HashMap<String,HashSet<Object>>();
|
||||
typeMap.put(type,map);
|
||||
var defList = f.getRootContainer(true).getAllContentsOfType(type)
|
||||
var iter = defList.iterator;
|
||||
while (iter.hasNext()) {
|
||||
var def = iter.next();
|
||||
var fiter = def.getAllContentsOfType(typeof(fielddef)).iterator;
|
||||
while (fiter.hasNext()) {
|
||||
var other = fiter.next();
|
||||
var name = other.getName();
|
||||
addNameEntryToSet(map, name, other);
|
||||
}
|
||||
}
|
||||
}
|
||||
var HashSet<Object> set = map.get(f.name);
|
||||
return (set != null && set.size > 1)
|
||||
}
|
||||
|
||||
@Check
|
||||
def void checkTokenNameIsUnique(contextfielddef f) {
|
||||
if (checkDuplicate(f)) {
|
||||
warning("context field names have to be unique", SleighPackage.eINSTANCE.getcontextfielddef_Name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
def boolean checkDuplicate(contextfielddef f) {
|
||||
var type = typeof(contextdef)
|
||||
var HashMap<String,HashSet<Object>> map = typeMap.get(type);
|
||||
// if map hasn't been initialized, initialize it
|
||||
if (map == null) {
|
||||
map = new HashMap<String,HashSet<Object>>()
|
||||
typeMap.put(type,map)
|
||||
var defList = f.getRootContainer(true).getAllContentsOfType(type)
|
||||
var iter = defList.iterator
|
||||
while (iter.hasNext()) {
|
||||
var def = iter.next()
|
||||
var fiter = def.getAllContentsOfType(typeof(contextfielddef)).iterator
|
||||
while (fiter.hasNext()) {
|
||||
var other = fiter.next()
|
||||
var name = other.getName()
|
||||
addNameEntryToSet(map, name, other)
|
||||
}
|
||||
}
|
||||
}
|
||||
var HashSet<Object> set = map.get(f.name);
|
||||
return (set != null && set.size > 1)
|
||||
}
|
||||
|
||||
@Check
|
||||
def void checkTokenNameIsUnique(VARSYM v) {
|
||||
if (checkDuplicate(v)) {
|
||||
warning("var names have to be unique", SleighPackage.eINSTANCE.VARSYM_Name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
def boolean checkDuplicate(VARSYM v) {
|
||||
var type = typeof(varnodedef)
|
||||
var HashMap<String,HashSet<Object>> map = typeMap.get(type);
|
||||
if (map == null) {
|
||||
map = new HashMap<String,HashSet<Object>>();
|
||||
typeMap.put(type,map);
|
||||
var defList = v.getRootContainer(true).getAllContentsOfType(type)
|
||||
var iter = defList.iterator;
|
||||
while (iter.hasNext()) {
|
||||
var def = iter.next();
|
||||
var fiter = def.getAllContentsOfType(typeof(vardef)).iterator;
|
||||
while (fiter.hasNext()) {
|
||||
var other = fiter.next();
|
||||
var name = other.varname.name;
|
||||
addNameEntryToSet(map, name, other);
|
||||
}
|
||||
}
|
||||
}
|
||||
var HashSet<Object> set = map.get(v.name);
|
||||
return (set != null && set.size > 1)
|
||||
}
|
||||
|
||||
@Check
|
||||
def void checkWarnExpensiveOperation(constraint c) {
|
||||
var op = c.compareOp
|
||||
if (op == null || op.equals('=')) {
|
||||
return;
|
||||
}
|
||||
// TODO: Could check if the op token size is small, don't warn
|
||||
// For token sizes, this should not be so expensive 2,3
|
||||
|
||||
// comparison operations can be expensive
|
||||
warning("comparison can be expensive, and should be used sparingly", SleighPackage.eINSTANCE.getconstraint_CompareOp)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user