Reintroduce a handful of binder tests
This change adds a few binder tests, and fixes package dependency enumeration to be deterministic by using stable map enumeration.
This commit is contained in:
parent
289a0d405d
commit
9455483d27
|
@ -4,211 +4,92 @@ package binder
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
ast "github.com/marapongo/mu/pkg/astlegacy"
|
||||
"github.com/marapongo/mu/pkg/compiler/core"
|
||||
"github.com/marapongo/mu/pkg/compiler/errors"
|
||||
"github.com/marapongo/mu/pkg/compiler/metadata"
|
||||
"github.com/marapongo/mu/pkg/diag"
|
||||
"github.com/marapongo/mu/pkg/errors"
|
||||
"github.com/marapongo/mu/pkg/util/contract"
|
||||
"github.com/marapongo/mu/pkg/util/testutil"
|
||||
"github.com/marapongo/mu/pkg/workspace"
|
||||
)
|
||||
|
||||
func TestBadMissingStackName(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__missing_stack_name")
|
||||
func testBind(paths ...string) *testutil.TestDiagSink {
|
||||
// Create the test directory path.
|
||||
pwd, _ := os.Getwd()
|
||||
testdir := filepath.Join(append([]string{pwd}, paths...)...)
|
||||
|
||||
// Check that the compiler complained about a missing Stack name.
|
||||
d := errors.ErrorMissingStackName
|
||||
assert.Equal(t, 1, sink.Errors(), "expected a single error")
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml", d.Message),
|
||||
sink.ErrorMsgs()[0])
|
||||
// Create a test sink, so we can capture and inspect outputs.
|
||||
sink := testutil.NewTestDiagSink(testdir)
|
||||
|
||||
// Create the compiler machinery (context, reader, workspace).
|
||||
ctx := core.NewContext(testdir, sink, &core.Options{Diag: sink})
|
||||
reader := metadata.NewReader(ctx)
|
||||
w, err := workspace.New(ctx)
|
||||
contract.Assertf(err == nil, "Expected nil workspace error; got '%v'", err)
|
||||
|
||||
// Detect and read in the package.
|
||||
pkgpath, err := w.DetectPackage()
|
||||
contract.Assertf(err == nil, "Expected nil package detection error; got '%v'", err)
|
||||
pkgdoc, err := diag.ReadDocument(pkgpath)
|
||||
contract.Assertf(err == nil, "Expected nil package reader error; got '%v'", err)
|
||||
pkg := reader.ReadPackage(pkgdoc)
|
||||
|
||||
// Now create a binder and bind away, returning the resulting sink.
|
||||
if pkg != nil {
|
||||
b := New(w, ctx, reader)
|
||||
b.BindPackage(pkg)
|
||||
}
|
||||
return sink
|
||||
}
|
||||
|
||||
func TestBadStackSemVer1(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__stack_semver__1")
|
||||
func TestBadDepSemVer(t *testing.T) {
|
||||
sink := testBind("testdata", "bad__dep_semver")
|
||||
|
||||
// Check that the compiler complained about an illegal semantic version.
|
||||
d := errors.ErrorIllegalStackVersion
|
||||
assert.Equal(t, 1, sink.Errors(), "expected a single error")
|
||||
d := errors.ErrorMalformedPackageURL
|
||||
assert.Equal(t, 3, sink.Errors(), "expected an error for each bad semver")
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message, "badbadbad", "No Major.Minor.Patch elements found")),
|
||||
sink.ErrorMsgs()[0])
|
||||
}
|
||||
|
||||
func TestBadStackSemVer2(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__stack_semver__2")
|
||||
|
||||
// Check that the compiler complained about an illegal semantic version.
|
||||
d := errors.ErrorIllegalStackVersion
|
||||
assert.Equal(t, 1, sink.Errors(), "expected a single error")
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message, ">1.0.0",
|
||||
"Invalid character(s) found in major number \">1\"")),
|
||||
sink.ErrorMsgs()[0])
|
||||
}
|
||||
|
||||
func TestBadDepSemVer1(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__dep_semver__1")
|
||||
|
||||
// Check that the compiler complained about an illegal semantic version.
|
||||
d := errors.ErrorIllegalNameLikeSyntax
|
||||
assert.Equal(t, 1, sink.Errors(), "expected a single error")
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message, "dep1@badbadbad",
|
||||
fmt.Sprintf(d.Message, "dep1#badbadbad",
|
||||
"Illegal version spec: Could not get version from string: \"badbadbad\"")),
|
||||
sink.ErrorMsgs()[0])
|
||||
}
|
||||
|
||||
func TestBadDepSemVer2(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__dep_semver__2")
|
||||
|
||||
// Check that the compiler complained about an illegal semantic version.
|
||||
d := errors.ErrorIllegalNameLikeSyntax
|
||||
assert.Equal(t, 1, sink.Errors(), "expected a single error")
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message, "dep3@badbadbad",
|
||||
fmt.Sprintf(d.Message, "hub.mu.com/dep2#badbadbad",
|
||||
"Illegal version spec: Could not get version from string: \"badbadbad\"")),
|
||||
sink.ErrorMsgs()[0])
|
||||
}
|
||||
|
||||
func TestBadDepSemVer3(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__dep_semver__3")
|
||||
|
||||
// Check that the compiler complained about an illegal semantic version.
|
||||
d := errors.ErrorIllegalNameLikeSyntax
|
||||
assert.Equal(t, 4, sink.Errors(), "expected an error for each bad semver")
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message, "dep1@bad1",
|
||||
"Illegal version spec: Could not parse Range \"bad1\": "+
|
||||
"Could not parse comparator \"bad\" in \"bad1\"")),
|
||||
sink.ErrorMsgs()[0])
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message, "dep2@0.0",
|
||||
"Illegal version spec: Could not parse Range \"0.0\": "+
|
||||
"Could not parse version \"0.0\" in \"0.0\": No Major.Minor.Patch elements found")),
|
||||
sink.ErrorMsgs()[1])
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message, "dep3@bad3",
|
||||
"Illegal version spec: Could not parse Range \"bad3\": "+
|
||||
"Could not parse comparator \"bad\" in \"bad3\"")),
|
||||
fmt.Sprintf(d.Message, "https://hub.mu.com/dep3/a/b/c/d#badbadbad",
|
||||
"Illegal version spec: Could not get version from string: \"badbadbad\"")),
|
||||
sink.ErrorMsgs()[2])
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message, "dep4@0.6.bad.ness.1",
|
||||
"Illegal version spec: Could not parse Range \"0.6.bad.ness.1\": "+
|
||||
"Could not parse version \"0.6.bad.ness.1\" in \"0.6.bad.ness.1\": "+
|
||||
"Invalid character(s) found in patch number \"bad.ness.1\"")),
|
||||
sink.ErrorMsgs()[3])
|
||||
}
|
||||
|
||||
func TestBadSymbolAlreadyExists(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__symbol_already_exists")
|
||||
|
||||
// Check that the compiler complained about a duplicate symbol.
|
||||
d := errors.ErrorSymbolAlreadyExists
|
||||
assert.Equal(t, 1, sink.Errors(), "expected a single error")
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message, "foo")),
|
||||
sink.ErrorMsgs()[0])
|
||||
}
|
||||
|
||||
func TestBadTypeNotFound1(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__type_not_found__1")
|
||||
func TestBadTypeNotFound(t *testing.T) {
|
||||
sink := testBind("testdata", "bad__type_not_found")
|
||||
|
||||
// Check that the compiler complained about the type missisng.
|
||||
d := errors.ErrorStackTypeNotFound
|
||||
d := errors.ErrorTypeNotFound
|
||||
assert.Equal(t, 1, sink.Errors(), "expected a single error")
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message,
|
||||
fmt.Sprintf("%v%vsomething/non/existent@%v",
|
||||
ast.DefaultRefProto, ast.DefaultRefBase, ast.DefaultRefVersion))),
|
||||
fmt.Sprintf("%v: %v%v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID,
|
||||
fmt.Sprintf(d.Message, "missing/package:bad/module/Clazz", "symbol missing")),
|
||||
sink.ErrorMsgs()[0])
|
||||
}
|
||||
|
||||
func TestBadTypeNotFound2(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__type_not_found__2")
|
||||
func TestGoodPrimitiveTypes(t *testing.T) {
|
||||
sink := testBind("testdata", "good__primitive_types")
|
||||
|
||||
// Check that the compiler complained about the type missisng.
|
||||
d := errors.ErrorStackTypeNotFound
|
||||
assert.Equal(t, 1, sink.Errors(), "expected a single error")
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID, "Mu.yaml",
|
||||
fmt.Sprintf(d.Message,
|
||||
fmt.Sprintf("%v%vsomething/non/existent@%v",
|
||||
ast.DefaultRefProto, ast.DefaultRefBase, ast.DefaultRefVersion))),
|
||||
sink.ErrorMsgs()[0])
|
||||
}
|
||||
|
||||
func TestBadMissingProperties(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__properties", "bad__missing")
|
||||
|
||||
d := errors.ErrorMissingRequiredProperty
|
||||
reqs := []string{"req_bool", "req_number", "req_service", "req_string"}
|
||||
assert.Equal(t, len(reqs), sink.Errors(), "expected an error per property")
|
||||
for i, req := range reqs {
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID,
|
||||
fmt.Sprintf(d.Message, req)),
|
||||
sink.ErrorMsgs()[i])
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadUnrecognizedProperties(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__properties", "bad__unrecognized")
|
||||
|
||||
d := errors.ErrorUnrecognizedProperty
|
||||
unks := []string{"unk_bool", "unk_number", "unk_service", "unk_string"}
|
||||
assert.Equal(t, len(unks), sink.Errors(), "expected an error per property")
|
||||
for i, unk := range unks {
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID,
|
||||
fmt.Sprintf(d.Message, unk)),
|
||||
sink.ErrorMsgs()[i])
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadPropertyTypes(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "bad__properties", "bad__types")
|
||||
|
||||
d := errors.ErrorIncorrectType
|
||||
exp := []string{"bool", "number", "service", "string"}
|
||||
got := []string{"string", "string", "bool", "float64"}
|
||||
assert.Equal(t, len(exp), sink.Errors(), "expected an error per property")
|
||||
for i, ty := range exp {
|
||||
assert.Equal(t,
|
||||
fmt.Sprintf("%v: %v%v: %v\n",
|
||||
diag.DefaultSinkErrorPrefix, diag.DefaultSinkIDPrefix, d.ID,
|
||||
fmt.Sprintf(d.Message, ty, got[i])),
|
||||
sink.ErrorMsgs()[i])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoodPredefTypes(t *testing.T) {
|
||||
sink := buildNoCodegen("testdata", "binder", "good__predef_types")
|
||||
|
||||
// Check that no errors are found when using predefined stack types.
|
||||
assert.Equal(t, 0, sink.Errors(), "expected no errors when binding to predef types")
|
||||
// Check that no errors are found when using primitive types.
|
||||
assert.Equal(t, 0, sink.Errors(), "expected no errors when binding to primitive types")
|
||||
}
|
||||
|
|
|
@ -52,11 +52,12 @@ func (b *binder) resolvePackageDeps(pkg *symbols.Package) {
|
|||
contract.Require(pkg != nil, "pkg")
|
||||
|
||||
if pkg.Node.Dependencies != nil {
|
||||
for _, depurl := range *pkg.Node.Dependencies {
|
||||
for _, dep := range pack.StableDependencies(*pkg.Node.Dependencies) {
|
||||
depurl := (*pkg.Node.Dependencies)[dep]
|
||||
// The dependency is a URL. Transform it into a name used for symbol resolution.
|
||||
dep, err := depurl.Parse()
|
||||
if err != nil {
|
||||
b.Diag().Errorf(errors.ErrorMalformedPackageURL, depurl, err)
|
||||
b.Diag().Errorf(errors.ErrorMalformedPackageURL.At(pkg.Node), depurl, err)
|
||||
} else {
|
||||
glog.V(3).Infof("Resolving package '%v' dependency name=%v, url=%v", pkg.Name(), dep.Name, dep.URL())
|
||||
if depsym := b.resolveDep(dep); depsym != nil {
|
||||
|
|
2
pkg/compiler/binder/testdata/Muspace.yaml
vendored
Normal file
2
pkg/compiler/binder/testdata/Muspace.yaml
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# This exists solely to stop the Mu compiler from going beyond this directory in its search for Mufiles, etc.
|
||||
|
6
pkg/compiler/binder/testdata/bad__dep_semver/Mu.yaml
vendored
Normal file
6
pkg/compiler/binder/testdata/bad__dep_semver/Mu.yaml
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
name: "binder/bad__dep_semver"
|
||||
dependencies:
|
||||
dep1: dep1#badbadbad
|
||||
dep2: hub.mu.com/dep2#badbadbad
|
||||
dep3: https://hub.mu.com/dep3/a/b/c/d#badbadbad
|
||||
|
18
pkg/compiler/binder/testdata/bad__type_not_found/Mu.yaml
vendored
Normal file
18
pkg/compiler/binder/testdata/bad__type_not_found/Mu.yaml
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
name: binder/bad_type_not_found
|
||||
modules:
|
||||
index:
|
||||
kind: Module
|
||||
name:
|
||||
kind: Identifier
|
||||
ident: index
|
||||
default: true
|
||||
members:
|
||||
x:
|
||||
kind: ModuleProperty
|
||||
name:
|
||||
kind: Identifier
|
||||
ident: x
|
||||
type:
|
||||
kind: TypeToken
|
||||
tok: missing/package:bad/module/Clazz
|
||||
|
4
pkg/compiler/binder/testdata/good__primitive_types/Mu.json
vendored
Normal file
4
pkg/compiler/binder/testdata/good__primitive_types/Mu.json
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "binder/good__primitive_types"
|
||||
}
|
||||
|
330
pkg/compiler/binder/testdata/good__primitive_types/Mu.out.json
vendored
Normal file
330
pkg/compiler/binder/testdata/good__primitive_types/Mu.out.json
vendored
Normal file
|
@ -0,0 +1,330 @@
|
|||
{
|
||||
"name": "binder/good__primitive_types",
|
||||
"modules": {
|
||||
"index": {
|
||||
"kind": "Module",
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"ident": "index"
|
||||
},
|
||||
"imports": [],
|
||||
"members": {
|
||||
"b": {
|
||||
"kind": "ModuleProperty",
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"ident": "b",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 11
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 12
|
||||
}
|
||||
}
|
||||
},
|
||||
"access": "public",
|
||||
"type": {
|
||||
"kind": "TypeToken",
|
||||
"tok": "bool",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 11
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 28
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"n": {
|
||||
"kind": "ModuleProperty",
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"ident": "n",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 2,
|
||||
"column": 11
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"column": 12
|
||||
}
|
||||
}
|
||||
},
|
||||
"access": "public",
|
||||
"type": {
|
||||
"kind": "TypeToken",
|
||||
"tok": "number",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 2,
|
||||
"column": 11
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"column": 25
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"s": {
|
||||
"kind": "ModuleProperty",
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"ident": "s",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 11
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 12
|
||||
}
|
||||
}
|
||||
},
|
||||
"access": "public",
|
||||
"type": {
|
||||
"kind": "TypeToken",
|
||||
"tok": "string",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 11
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 34
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
".init": {
|
||||
"kind": "ModuleMethod",
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"ident": ".init"
|
||||
},
|
||||
"access": "public",
|
||||
"body": {
|
||||
"kind": "Block",
|
||||
"statements": [
|
||||
{
|
||||
"kind": "ExpressionStatement",
|
||||
"expression": {
|
||||
"kind": "BinaryOperatorExpression",
|
||||
"left": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "b",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 11
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"operator": "=",
|
||||
"right": {
|
||||
"kind": "BoolLiteral",
|
||||
"raw": "true",
|
||||
"value": true,
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 24
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 28
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 29
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 29
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "ExpressionStatement",
|
||||
"expression": {
|
||||
"kind": "BinaryOperatorExpression",
|
||||
"left": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "n",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 2,
|
||||
"column": 11
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"column": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"operator": "=",
|
||||
"right": {
|
||||
"kind": "NumberLiteral",
|
||||
"raw": "42",
|
||||
"value": 42,
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 2,
|
||||
"column": 23
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"column": 25
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 2,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"column": 26
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 2,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 2,
|
||||
"column": 26
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "ExpressionStatement",
|
||||
"expression": {
|
||||
"kind": "BinaryOperatorExpression",
|
||||
"left": {
|
||||
"kind": "LoadLocationExpression",
|
||||
"name": {
|
||||
"kind": "Token",
|
||||
"tok": "s",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 11
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"operator": "=",
|
||||
"right": {
|
||||
"kind": "StringLiteral",
|
||||
"raw": "hello, mu",
|
||||
"value": "hello, mu",
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 23
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 34
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 35
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 3,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 3,
|
||||
"column": 35
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
"file": "index.ts",
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 5,
|
||||
"column": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
4
pkg/compiler/binder/testdata/good__primitive_types/index.ts
vendored
Normal file
4
pkg/compiler/binder/testdata/good__primitive_types/index.ts
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
export let b: boolean = true;
|
||||
export let n: number = 42;
|
||||
export let s: string = "hello, mu";
|
||||
|
|
@ -44,6 +44,7 @@ func (r *reader) ReadPackage(doc *diag.Document) *pack.Package {
|
|||
defer glog.V(2).Infof("Reading MuPackage '%v' completed w/ %v warnings and %v errors",
|
||||
doc.File, r.Diag().Warnings(), r.Diag().Errors())
|
||||
}
|
||||
contract.Assert(len(doc.Body) != 0)
|
||||
|
||||
// We support many file formats. Detect the file extension and deserialize the contents.
|
||||
m, has := encoding.Marshalers[doc.Ext()]
|
||||
|
|
32
pkg/pack/stable.go
Normal file
32
pkg/pack/stable.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2016 Marapongo, Inc. All rights reserved.
|
||||
|
||||
package pack
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/marapongo/mu/pkg/tokens"
|
||||
)
|
||||
|
||||
func StableDependencies(deps Dependencies) []tokens.PackageName {
|
||||
sorted := make(packageNames, 0, len(deps))
|
||||
for dep := range deps {
|
||||
sorted = append(sorted, dep)
|
||||
}
|
||||
sort.Sort(sorted)
|
||||
return sorted
|
||||
}
|
||||
|
||||
type packageNames []tokens.PackageName
|
||||
|
||||
func (s packageNames) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s packageNames) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
func (s packageNames) Less(i, j int) bool {
|
||||
return s[i] < s[j]
|
||||
}
|
Loading…
Reference in a new issue